들어가기에 앞서..
웹 개발을 하거나 네트워크에 대한 기본적인 흐름을 알고 싶은데
개념적인 내용과 실제 물리적인 내용들이 머리속에서 뒤죽박죽 되어 파편화 되어 있는 분들을 위해(내가 그랬다..)
면접에서도 자주 나오는(나왔던) 질문이자 파편화 되어 있던 지식들을 하나의 큰 흐름으로 이해 할 수 있게 도와줬던
브라우저 검색창에 www.google.com을 입력하면 일어나는 일에 대해서 알아보는 시간을 가져보자
우리는 인터넷을 통해 수 많은 작업을 진행한다.
정보를 검색하고 물건을 사거나, 메일로 메세지를 주고 받으며, 강의를 듣거나 음악을 감상한다.
이러한 모든 작업들은
내가 클라이언트가 되어 쇼핑몰이나 네이버 메일등과 같은 웹서버와 통신을 함으로써 일어날 수 있는 과정들이다.
여기서 통신이라 함은 커뮤니케이션 즉, 상호작용인 것이다.
이런 상호작용에서 한쪽이 일방적으로 규칙을 정하고 그 규칙에 따라 커뮤니케이션 한다면 받는 쪽에서는 그 규칙을 이해 할 수 없거나 이해 한다고 해도 잘못 이해 하는 상황이 발생 할 수 있다.
실제로 우리나라에서는 OK라는 손가락 모양을 "좋다, 알겠다" 라는 의미로 사용하지만 남미에서는 그것을 욕의 의미로 사용한다.
이런 상황에서 내가 남미 사람과 커뮤니케이션 할 때 OK라는 손 모양을 하게 되면 내가 전달하고자 하는 의미가 아닌 다른 의미로 잘못 이해하는 상황이 생길 것이다.
이렇게 상호간의 요청과 응답에 있어 규칙을 정하고 정해진 규칙에 따라 정확하고 효율적으로 데이터를 주고 받기 위해 통신 규약, 즉 약속이 만들어 졌다.
웹에서는 그 약속을 Protocol이라고 하는데 이러한 프로토콜에는 대표적으로 HTTP, TCP, IP, UDP 등 이 있다.
www.google.com 의 최종 목표
크롬에 http://www.google.com 을 입력함으로써 내가 원하는 것은 결국 웹 서버로 부터 요청(request)한 구글 홈페이지를 응답(response) 받는 것이다.
이 과정을 조금 더 자세하게 살펴보면
- 어플리케이션 소프트웨어(크롬)에서 데이터를 요청
- 그 요청을 전송 소프트웨어(OS 레벨)에서 전송
- 해당 전송을 물리적 전자신호로 변경
- 물리적인 네트워크 장비를 통해 전송
이렇게 4가지의 동작을 거친다고 볼 수 있다.
이 통신 또한 약속이 있어야 원활한 통신이 될 것이다. 그럼 여기서 통신을 하기 위해 어떤 약속을 정했을까?
웹 클라이언트와 웹 서버가 통신을 하기 위해 정한 약속이 바로 HTTP(Hypertext Transfer Protocol) 이다.
http://www.google.com 앞에 쓰여진 http:// 가 바로 "우리 데이터 주고 받을 때 http 약속을 사용하자" 라는 의미인 것이다.
그리고 전송 소프트웨어에서 전송을 할 때 정하는 약속을 TCP(Transmission Control Protocol),
전달 할 목적지와 같은 정보에 대한 약속을 IP(Internet Protocol)라고 하여
최종적으로 우리가 사용하는 인터넷이 TCP/IP를 기반으로 한 HTTP 프로토콜 통신 이 되는 것이다.
데이터는 4층짜리 빌딩을 거친다
TCP/IP 프로토콜은 개념적으로 계층을 구분짓고 각 계층에 역할을 부여, 수행하게 하여 효율적으로 데이터를 전달하는데
다음과 같이 4가지의 계층으로 나뉜다.
응용 계층 - 어플리케이션 |
전송 계층 - TCP |
인터넷 계층 - IP |
네트워크 인터페이스 계층 - 이더넷 |
그렇다면 본격적으로 데이터가 어떻게 전달 되고
계층별로 어떤 역할을 수행하는지 알아보자
1. 응용계층 - 사용자와 상호작용 할게
가장 먼저 응용 계층에서는 사용자와 직접적인 상호작용이 일어난다.
여기서 이 상호작용을 담당하는 것이 바로 응용 프로그램(크롬)이고 이 프로그램은 Http 프로토콜을 호출한다.
www.google.com 은 정확히 http://www.google.com:80 이다. 여기서 뒤에 붙은 80은 포트 번호(특정 프로세스나 애플리케이션을 식별하기 위해 사용되는 숫자)로 HTTP 프로토콜의 포트번호가 80번이기 때문에 www.google.com만 입력하더라도 자동으로 80이 붙은 것으로 인식한다.
호출된 Http 프로토콜은 클라이언트의 메세지에 HTTP 헤더를 붙여 HTTP 메세지를 생성한다.
- HTTP 헤더에 포함되는 대표적인 정보
- 컨텐트 타입, 쿠키, 상태 코드
헤더에 포함되는 대표적인 정보를 보면 알 수 있듯,
응용계층에서는 사용자와의 상호작용 뿐만 아니라
- 데이터의 형식과 프로토콜 정의
- 데이터 보안, 네트워크 서비스 및 자원 관리
와 같은 중요한 기능을 수행한다.
이렇게 생성된 HTTP 메세지는 전송계층에 전달되는데, 이 때 응용프로그램에서 OS 레벨로 데이터가 전송된다.
2. 전송계층 - 이 데이터는 내가 보증한다
전송계층에서는 데이터의 전송 및 흐름의 신뢰성을 확보하기 위해 모든 노력을 기울인다.
전송 목적지와 연결을 설정하고
응용계층으로부터 전달 받은 데이터를 검증하며
흐름 제어, 혼잡 제어와 같은 기법을 활용하여 전송 환경을 최적화 한다.
여기서 Http가 사용하는 TCP는
이 연결에 대한 신뢰성을 보장하기 위해
요청을 받는 서버가 요청을 받을 수 있는 상태인지 체크하는 전처리 과정을 진행한다.
❓ 무슨 전처리 과정?
간단하게 요약하면
- 클라이언트 : 통신할 준비 됐어 ?
- 서버 : 응 됐어 너도 준비 됐어?
- 클라이언트 : 오케이 나도 준비 됐어
이런 과정이다.
이 과정을 총 3번의 메세지 교환이 이루어진다 하여 🤝3-way-handshaking이라 부르는데
조금 더 구체적으로 살펴보자
TCP 헤더에는 제어 정보를 나타내는 Flag 필드가 존재하고
이 Flag 필드는 비트로 구성된 6가지의 제어정보가 있다.
3-way-handshaking에서는 그 중 ACK,SYN
- ACK (Acknowledgment): 데이터의 확인 응답
- SYN (Synchronize): 연결 설정 요청
이 두가지 신호를 가지고 통신하게 되는데
- 클라이언트가 서버에게 접속을 요청하는 SYN Flag를 보낸다 (통신할 준비 됐어 ?)
- 서버가 새로운 SYN과 클라이언트의 SYN에 1을 더한 ACK Flag를 추가해 다시 보낸다 (응 됐어 너도 준비 됐어?)
- 클라이언트가 서버로부터 받은 SYN에 1을 추가해 ACK Flag를 보낸다 (오케이 나도 준비 됐어)
이렇게 3번의 처리로 연결 설정이 완료되고 신뢰성을 기반으로 데이터를 보낼 준비가 완료되면
전달받은 데이터인 HTTP 메세지에 TCP 헤더를 붙여 세그먼트로 만든다.
- TCP 헤더에 포함되는 대표적인 정보
- 시작 포트번호, 목적지 포트번호
이렇게 생성된 세그먼트를 인터넷 계층에 전달한다.
3. 인터넷 계층 - 데이터를 보내보자
인터넷 계층에서는 전송계층에서 보증한 신뢰성 있는 데이터를 어디로 어떻게 보낼지를 정한다.
😎 : 아 어디로 보낼지 알아 www.google.com 여기잖아 ?
맞다. 그런데 문제가 있다. 컴퓨터는 단순해서 고등생명체인 인간의 언어를 알아 듣지를 못한다.
그래서 이 도메인정보를 IP주소로 바꿔줘야 하는데
그 역할을 해주는 것이 바로 DNS(Domain Name System)이다.
DNS는 www.google.com 에 대응하는 IP주소를 알고있다.
(DNS는 로컬 DNS부터 Root DNS 등 다양한 DNS가 있고 여러번의 질의를 통해 답을 얻는데, 결국 연결된 DNS중 누군가는 반드시 해당 도메인에 대한 정보를 알고 있다.)
우리는 DNS에게 IP주소를 질의하고 DNS는 해당 도메인에 매핑된 IP주소를 결과로 넘겨준다.
이제 목적지인 서버의 IP주소를 알았으니,
전달받은 세그먼트에 IP 헤더를 붙여 패킷으로 만들고
- IP 헤더에 포함되는 대표적인정보
- 시작 IP주소와, 목적지 IP주소
신명나게 라우팅 하여 데이터를 보내면 된다.
🤔 : 라우팅 ?? 그게뭔데
라우팅은 라우터를 찾아가는 행위를 말하는데, 이 때 사용되는 개념을 정리하자면 다음과 같다.
- 라우터 : 네트워크와 네트워크를 연결해주는 인터넷 장비
- 라우팅 : 라우터가 다음 목적지의 라우터를 찾아가는 행위
- 라우팅 테이블 : 다음 목적지에 대한 정보가 써있는 이정표
결국 라우팅이라 함은 네트워크를 찾아가는 과정을 얘기한다.
이렇게 생성된 패킷은 네트워크 인터페이스 계층으로 전송된다.
4. 네트워크 인터페이스 계층 : 진짜 전기신호로 바꿔줄게
네트워크 인터페이스 계층에서는 데이터를 실제 물리적인 전자 신호로 변경해주는 역할을 한다.
그리고 이 전자 신호는 MAC 주소를 통해 네트워크 장비로 전달되는데
🤔 : IP 주소 까지는 알겠는데, MAC주소는 뭐지 ?
IP주소가 네트워크 상에서 컴퓨터 자체를 의미하는 논리적인 식별자 라면
MAC주소는 전자 신호를 주고 받기 위한 실제 물리적인 장치들의 식별자 인 것이다.
그렇다면, 우리는 최종 목적지인 google 웹 서버의 MAC 주소를 알아야 할까?
아니다. 이 광범위한 인터넷 세상에서 데이터를 주고 받기 위해서는 물리적으로 굉장히 많은 장치들을 거쳐야 한다.
따라서, 여기서 필요한 MAC주소는 당장 이 전자 신호를 보낼 공유기의 MAC주소 인 것이다.
여기서 공유기는 다른 네트워크들과의 통신이 가능하기 때문에 게이트웨이 라고도 부른다.
그럼 이 게이트웨이의 MAC주소는 어떻게 알아내는 것일까
우리는 이미 게이트웨이의 IP주소를 알고 있다.
명령프롬프트에서 ipconfig를 입력해본 적이 있을 것이다.
여기서 기본 게이트웨이 . . . . 하고 나와있는 저 숫자가 바로 게이트웨이의 ip 주소 인 것이다.
그럼 DNS와 동일하게 그 IP주소를 MAC주소로 변경해줄 누군가가 있어야 하는데
이 변환 역할을 해주는 것이 바로 ARP(Address Resolution Protocol) 이다.
이렇게 변경된 MAC주소를 포함하기 위해
전달받은 패킷에 이더넷 헤더를 붙여 물리적인 전자 신호인 프레임 으로 변경한다.
- 이더넷 헤더에 포함되는 대표 정보
- MAC주소
5. 전송!!
자 이제 모든 준비는 완료 됐다. 사용자의 요청(메세지)은 최종적으로 물리적 신호인 프레임이 되었으며 이 프레임은 네트워크 장치들을 거쳐 최종 목적지에 도달하게 될 것이다.
위에서 알아낸 게이트웨이 MAC주소를 통해 프레임을 게이트 웨이로 전송하고
게이트웨이 라우터에서는 최종 목적지인 구글 서버로 가기 위한 징검다리 역할을 하는 또 다른 라우터를 찾고 연결하고 ... 넘겨주고 연결하고 넘겨주고... 이렇게 수많은 라우터를 거쳐 결국 사용자의 메세지가 구글 서버에 도달하게 되는 것이다.
6. 데이터가 도착하면 서버에서는?
서버에 도착한 프레임은
클라이언트의 TCP/IP 4계층의 동작과 똑같지만(?) 역순으로 동작한다고 보면 된다.
- 이더넷의 헤더를 해석하고 벗겨내고
- IP 헤더를 해석하고 벗겨내고
- TCP 헤더를 해석하고 벗겨내고
- 요청한 데이터에 대한 분석을 하고
해당 요청에 알맞는 데이터를 클라이언트에 반환하는 것이다!
(반환은 앞서 보았던 클라이언트에서 요청을 보낼 때와 똑같은 과정을 거친다. 그래서 생략하겠다 😅)
7. 다 받았습니다~ 종료합니다!
이렇게 전체 HTTP요청과 응답의 과정이 끝나면 이제 클라이언트와 서버간의 연결을 끊을 차례다.
(통화하다가 서로 할 얘기 끝났으면 통화 종료 하듯)
연결을 끊을 때도 TCP의 제어 비트를 통한 handshaking 기법이 사용되는데
🤓 : 아 그럼 3-way-handshaking이 또 나오는구나!
라고 생각 할 수 있겠지만
아니다. 이번엔 4-way-handshaking이다(!).
여기선 3-way-handshaking과 다르게 SYN대신 FIN 을 사용한다.
- FIN (Finish): 연결 종료 요청을 나타냄
연결이 종료되는 상황을 간략하게 표현해보면
- 클라 : 종료 한다? (클라이언트가 서버에게 접속 종료를 요청하는 FIN Flag를 보낸다)
- 서버 : 어 종료한다고? 오케이 (서버가 FIN을 확인했다는 ACK Flag를 보내고 이 통신이 끝날때까지 기다림)
- 클라 : 오케이 한거 들었지? 종료할게~(서버가 FIN Flag를 보낸다)
- 서버 : 오케이 수고~ (클라이언트가 서버로부터 받은 FIN을 확인했다는 ACK Flag를 보낸다)
이렇게 4단계의 과정을 거치는데
여기서 한가지 문제가 있다.
네트워크의 상황에 따라 클라이언트에게 보낸 데이터가 마지막으로 보낸 FIN 요청보다 늦게 도착 하는 상황이 생길 수도 있다는 것이다(!)
클라이언트에서는 이렇게 데이터가 소실되는 만약의 경우를 대비하여 서버로부터 FIN 플래그를 받더라도 연결을 끊지 않고 일정 시간 기다리는데 이를 TIME_WAIT 라고 한다.(정직한 번역)
이렇게 일정 시간 기다리고 데이터를 전부 받았다고 판단하면 서버와의 연결을 종료한다.
8. 길고 긴 과정들을 거쳐
한번쯤 TCP가 느리다는 얘기를 들어 본 적이 있을 것이다.
위 과정을 거친 우리는 이미 답을 알고 있다.
🤔 : 한번도 이렇게 긴데 데이터 보낼 때 마다 이 과정을 3번,4번씩 한다고?
네트워크에서나 컴퓨터에서나 결국 물리적인 거리가 멀면 느릴 수 밖에 없는데
그 먼 구글서버(광통신이 아무리 잘 되어 있다고 하지만 그래도 멀다..)를 몇번이나 왔다갔다 해야한다고 생각해보자
느릴 수 밖에 없지 않은가? 그렇다면 왜 이렇게 느린 TCP를 사용한걸까?
HTTP가 TCP를 사용 했던 이유는
HTTP가 개발된 초기의 웹 페이지 및 파일 전송에 필요한 요구사항을 충족시키는데 적합했고,
신뢰성과 안정성이 보장되어야 하는 당시 네트워크의 기술 상황에 잘 어울리는(인터넷 사용량도 지금보다 적었고 속도와 대역폭의 제약이 존재) 프로토콜이였기 때문이다.
Hello-World 라는 메세지를 보냈는데 받는쪽에서 Hell-World로 받으면 큰 문제가 생길 것이다 !
안정성과 신뢰성을 보장하기 위해 TCP는 3-way-handshaking 뿐 아니라 흐름제어, 오류제어, 혼잡제어 기법을 사용하므로 당시의 상황(정확도가 생명)에서 아주 매력적인 프로토콜이였을 것으로 생각된다.
*참고*
현재의 발전된 네트워크 기술에는 TCP의 느린 속도가 발목을 잡는 상황이 생겨 HTTP 3 버전 부터는 UDP를 채용한 QUIC 프로토콜을 사용하는 등의 변화가 생기고 있다.
마치며..
이렇게 주소창에 www.google.com 을 입력하면 발생하는 일에 대해서 알아봤는데
해당 내용들은 많이 추상화 되어 있는 수준이며 생략된 내용들도 굉장히 많다.
예를 들어 사실은 https://www.google.com:443 으로 바뀐다던지..
각 계층별 헤더에 들어가는 정보 라던지
서버쪽에서 데이터를 처리하는 웹서버, WAS 등등
전체적인 흐름을 가져가는데 이해하는 것에 초점이 있는 글이였기에 좀 더 자세한 내용들은 네트워크에 대한 학습으로 채워야 한다!!