CS/Network

(TIR+4) ③ 브라우저는 OS의 프로토콜 스택에 메시지 송신을 의뢰한다

Joonfluence 2020. 11. 18. 10:07

 

 지난 시간에는 DNS 서버와의 통신을 통해, URL에 숨겨져 있는 웹 서버의 IP 주소를 알아내는 것까지 알아보았다. 이번에는 브라우저가 OS 내부에 존재하는 프로토콜 스택에 의뢰하는 과정과 실제 내부 동작에 대하여 살펴볼 예정이다. 

 

 

 이미 프로토콜 스택에 대해서는 다룬 바 있다. 위의 그림을 참조하여 보면, 이미 웹 브라우저는 HTTP를 통해 전송될 HTTP Request 메세지는 작성한 상태이므로 5번 Layer를 지난 상태이다. 그러나 데이터가 실제로 전송되기 위해선, OS 내부의 네트워크 제어용 소프트웨어(프로토콜 스택, 4번&3번&2번 Layer)와 네트워크용 하드웨어(LAN 어댑터, 1번 Layer)가 브라우저에서 받은 메시지를 서버에 송출하여야 한다. 이를 위해 브라우저는 프로토콜 스택에 메시지 송신을 의뢰하는데, 이는 Socket 라이브러리 프로그램을 통해 가능하다. 해당 프로그램 안에는 프로토콜 스택에 대한 호출 순서를 결정하는 순서가 결정되어 있어, 올바른 순서대로 데이터가 전송될 수 있도록 돕는다. 

 

호출 순서와 프로토콜 스택의 실제 동작

 

1) 소켓의 작성 단계

 

 

 데이터 송/수신 동작을 하기에 앞서 클라이언트 측과 서버 측을 파이프로 연결하는 동작이 필요한데, 파이프 양 끝에서 출입구 역할을 하는 '소켓'이 필요하다. 클라이언트 측에서 소켓을 만드는 방법은 소켓 라이브러리의 Socket()을 호출해주면, 프로토콜 스택에서는 의뢰에 따라 한 개의 소켓을 만든다. 이는 소켓 한 개 분량의 메모리 영역을 확보하는 일이며, 소켓의 제어 정보(프로토콜 스택의 동작을 제어하기 위한 정보)를 기록한다. 또한 소켓을 나타내는 디스크립터(프로토콜 스택의 내부에 있는 다수의 소켓 중 어느 것을 가리키는지를 나타내는 정보)를 브라우저에 전달해준다. 이는 복수의 데이터 송/수신이 일어나는 상황에 필요하다. 이는 모두 TCP 프로토콜 계층에서 작업이 이뤄진다. 

 

2) 파이프를 연결하는 접속 단계 

 

 다음으론 만든 소켓을 서버측의 소켓에 접속하도록 프로토콜 스택에 의뢰하는 과정이 필요하다. 이는 브라우저가 소켓 라이브러리에서 connect()를 호출함으로써 가능하다. 이 때 디스크립터, 서버의 IP 주소, 서버의 포트 번호 정보를 프로토콜 스택에 전달한다. 디스크립터는 애플리케이션이 소켓을 식별할 때 활용되며, IP 주소와 포트번호는 클라이언트와 서버 간에 상대의 소켓을 식별할 때 사용된다. 참고로 IP 주소는 DNS 서버로부터 받아온 상태이며, 포트번호는 웹에선 80번으로 약속되어 있다. 

TCP Header에는 송/수신처의 포트번호, 시퀀스번호, ACK 번호 등이 포함된다

 접속 동작의 첫번째 동작은 접속을 나타내는 제어 정보를 기록한 TCP 헤더를 만드는 것이다. 제어 정보에는 클라이언트와 서버가 서로 연락을 절충하기 위해 주고 받는 데이터 정보와 소켓에 기록하여 프로토콜 스택의 동작을 제어하기 위한 정보가 있다. 전자는 서로 간의 데이터를 잘 주고 받았는지 확인하는 것을 말하며, 후자에는 애플리케이션에서 통지된 정보, 통신 상대로부터 받은 정보 등을 말한다. 헤더가 완성되면 통신 상대와의 사이에 제어 정보를 주고받아 소켓에 필요한 정보를 기록하고 데이터 송/수신이 가능한 상태로 만든다. 구체적인 예를 들면, 클라이언트측의 IP 주소나 포트번호를 서버측에 알려주는 것이다. 이 때 송/수신하는 데이터를 일시적으로 저장하는 메모리 영역이 필요한데, 이를 '버퍼 메모리'라고 한다. 

 이렇게 TCP 헤더를 만들면 이것을 IP 담당 부분에 건네주어 서버측에 송신하도록 의뢰한다. 그러면 IP 담당 부분이 패킷 송신 동작을 실행하고 네트워크를 통해 패킷이 서버에 도착하면 서버측의 IP 담당 부분이 이것을 받아 TCP 담당 부분에 건네준다. 이후 서버측의 TCP 담당 부분이 TCP 헤더를 조사하여 기록되어 있는 수신처 포트 번호에 해당하는 소켓을 찾는다. 그런 후 필요한 정보를 기록하고 접속 동작이 진행중이란 상태를 응답으로 돌려보낸다(이 과정을 Three way handshaking이라고 한다. 아래에 더욱 자세하게 설명하였다). 이로써 소켓은 데이터를 송/수신할 수 있는 상태가 된다. 

 

3) 메시지를 주고받는 송/수신 단계 

 

 소켓이 상대측과 연결되면, 소켓에서 데이터를 쏟아부어 상대측의 소켓에 데이터가 도착한다. 우선 애플리케이션은 송신 데이터(사용자가 입력한 URL을 바탕으로 만든 HTTP 리퀘스트 메시지)를 메모리에 준비하고 send(혹은 write)를 호출하면 송신 데이터를 프로토콜 스택에 건네주는 곳부터 시작된다. 프로토콜 스택은 받은 데이터를 송신용 버퍼 메모리 영역에 저장하고 MTU(한 패킷으로 운반할 수 있는 디지털 데이터의 최대 길이) & MSS(헤더를 제외하고 한 개의 패킷으로 운반할 수 있는 TCP의 데이터의 최대 길이)와 타이밍(프로토콜 스택 내부에 타이머가 있어 애플리케이션의 송신 속도가 너무 느려지는 경우 송신 동작을 실행한다)를 판단 기준으로 삼고 송신한다. 

 본격적인 송신에 앞서, TCP에는 송신한 패킷이 상대에게 올바르게 도착했는지 확인하고, 도착하지 않았으면 다시 송신하는 기능이 있어 패킷을 송신한 후 확인 동작으로 넘어간다. 이는 시퀀스 번호(데이터 조각을 분할할 때 조각이 통신 개시부터 몇 번째 바이트인지 세어둔 값)와 ACK 번호(다음에 받길 기대하는 패킷의 번호, 데이터를 어디까지 수신했는지 알려주어 가능하다)를 TCP 헤더에 기록하고 해당 데이터들을 서버 측과 교신하는 과정을 거침으로써 가능하다. 

Three way handshaking 과정  (출처 :  whenday.tistory.com/18  ) 

 클라이언트(A)에서는 SYN 패킷(연결을 요청할 때 사용하는 패킷. 패킷안에는 SEQ와 ACK라는 정보가 들어으며, 현재는 서버로 데이터에 관한 시퀀스 번호의 초기값을 담고 있다)을 서버(B)로 보낸다. 그러면 B가 A에게 패킷을 잘 받았고, 연결요청을 수락하는 패킷을 보낸다. 이러한 패킷을 SYN+ACK메세지라 칭하며, SEQ에 2000이라는 넘버를 부여하고, 전에 받은 패킷번호에서 +1을 하여서 다음에 받을 패킷의 번호를 설정하여 ACK를 같이 보낸다. 세 번째로 A가 B에게 패킷을 잘 받았고, 데이터를 송수신 하자는 패킷을 보낸다. 받은 패킷의 번호가 2000이었으니 ACK로 다음에 받을 패킷의 번호가 2001이라는것과 현재 보내는 패킷이 전에 보낸 패킷의 다음 패킷이라는 의미의 1001이라는 번호로 SEQ에 설정하여 보낸다. 이 과정을 통칭하여 Three way hanshaking이라고 한다. 

 

 그런 후, 프로토콜 스택이 데이터를 서버에 전송한다. 소켓에는 연결된 상대가 기록되어 있으므로 디스크립터로 소켓을 지정하면 연결된 상대가 판명되어 그곳을 향해 데이터를 송신한다 (자세한 과정은 이 글을 참고 바랍니다). 서버는 수신 동작을 통해 받은 데이터 내용을 조사하고 적절한 처리를 실행하여 응답 메세지를 반송한다. 

 

4) 연결 끊기 단계 

 

  애플리케이션이 송신해야 하는 데이터를 전부 송신 완료했다고 판단하면 서버에서 연결을 끊어 소켓을 말소한다. 과정은 다음과 같다. 서버측의 어플리케이션에서 먼저 close를 호출하면 서버측의 프로토콜 스택이 TCP 헤더를 만들고, 여기에 연결 끊기를 나타내는 정보를 설정한다. 클라이언트 측에서도 close를 호출하여 데이터 송/수신 동작을 끝낸다. 그런 후 소켓을 ㅁ말소한다.  

 이 과정은 앞선 글에서 설명하진 못했지만, DNS 서버로부터 리졸버를 통해 IP 주소를 받아오는 과정과 같다. 다만 소켓 통신 과정에선 TCP를 활용하였으며, DNS 서버에 대한 조회 작업은 UDP가 활용됐다는 점만 다를 뿐이다. 

 

느낀점

 

 이 책의 내용들을 살펴보면서 막연하게만 느껴지던 TCP와 IP에 대하여, 조금이나마 감을 잡을 수 있었다. 조금 더 욕심을 내어, 남들에게 설명할 수 있는 수준으로 알아가고 싶다. 화이팅하자!!

 

내용 출처

 

 

[TCP/IP] TCP/IP 송수신 과정

TCP기반의 소켓이 연결 되어서 데이터를 송,수신하고 종료 되기까지 총 3단계를 거치게 된다. 첫 번째 단계 : 연결 설정 위의 흐름을 하나하나 분석해보자면 첫 번째로 A가 B에게 연결을 요청하는

whenday.tistory.com

 

반응형