쾌락코딩

브라우저에 URL을 입력하면 일어나는 일 (2)

|

이전 장에서 브라우저가 os의 프로토콜 스택으로 http request 메시지를 전달해 주는 것 까지 알아보았다. 이제 프로토콜은 전달 받은 메시지를 어떻게 처리하는지 알아볼 차례다.

프로토콜 스택

프로토콜 스택이 무엇인지 알기 전에, 프로토콜은 어디서 정보를 얻어오고, 또 어디로 요청을 하는지, 그 흐름을 그려보았다.

protocol_stack

큰 흐름은 위에서 아래로 흐른다. 프로토콜 스택은 app(브라우저)에서 메시지를 전달 받는다. 메시지를 아주 작은 데이터인 패킷들로 나누고, 수신처 주소등의 제어 정보를 덧붙인다. 그리고 프로토콜 스택과 LAN어댑터가 연대하여 패킷을 전기나 빛의 신호로 변환하고, LAN어댑터가 실제로 송수신 동작, 즉 케이블에 대해 신호를 송수신하는 동작을 실행한다.

결과적으로 프로토콜 스택이란, TCP 프로토콜을 사용하여 데이터 송수신을 담당하는 부분과, UDP를 사용하여 송수신을 담당하는 부분, 또 IP를 사용하는 부분의 집합에 다른 부가적인 기능이 보함된 것이라고 볼 수 있을 것 같다.

서버에 접속 (통신 가능한 상태로 만들기- 통로 만들기)

브라우저에서 프로토콜 스택으로 메시지를 전달하면 프로토콜 스택은 여러가지 부가정보를 메모리에 저장한다. 부가적인 정보란, 통신 동작을 제어하기 위한 제어 정보인데, 예를 들면 통신 상대의 IP주소, 포트 번호, 오류 유무, 전송 시간, 데이터 오프셋 등등 꽤 많은 정보가 있다. 프로토콜 스택은 이 제어 정보를 참조하면서 오류를 제어하거나, 재송신하거나 등등의 일을 한다.

부가적인 정보는 누가 어떻게 저장하는가?

프로토콜 스택이 tcp 통신을 의뢰받았다면 부가적인 정보들은 위의 그림에서 tcp박스가 담당한다. 정확히 말하자면 부가적인 정보들을 담을 메모리 확보 절차를 소켓 작성이라고 한다. tcp박스, 더 큰 개념으로 프로토콜 스택이 소켓을 작성을 완료하면 브라우저에게 이 사실을 알리고, 언제든 이 소켓을 사용해 통신할 수 있게끔 일종의 리모콘(?)을 준다.

부가적인 제어 정보는 매번 전송된다.

tcp_header

그림에서 보듯이 통신을 위한 부가적인 제어 정보는 포트 번호, 시퀀스 번호(송신 데이터의 일련 번호), ACK 번호(수신 데이터의 일련 번호) 등 많은 정보가 있다. 이런 정보는 클라이언트와 서버가 대화할 때 마다 늘 필요하다. 따라서 클라이언트와 서버 사이에 주고받는 패킷의 맨 앞부분에 추가하는데, 이 추가하는 영역을 헤더 영역이라고 한다. 물론 ip영역에서도 ip나름의 헤더가 붙게된다.

3-way-handshake

클라이언트 컴퓨터의 tcp 부분에서 헤더를 만들고나면 tcp역시 ip 부분에 헤더를 건네주며 송신을 의뢰한다. IP부분이 패킷 송신 동작을 실행하고 네트워크를 통해 패킷이 서버에 도착하면 서버측의 IP부분이 이것을 받아 서버측의 TCP 부분으로 넘겨주는 방식이다.

TCP통신 방식은, 최초 통신때 이런 방식으로 서버와 클라이언트 사이에 파이프와 같은 연결 통로를 확보해야 한다. 파이프가 연결되어야 데이터를 마음껏 주고 받을 수 있기 때문인데, 이 초기 설정 과정에 3-way-handshake 방식이 사용된다.

쉽게 설명하자면 아래와 같이 3단계를 거친다.

  1. 클라이언트 : 서버야, 너와 통신하고 싶어! 너가 이 메세지를 받았다면 잘 받았다고 나한테 알려줘. 그럼 이만!

  2. 서버 : 그래 클라이언트야. 네가 보낸 메세지 잘 받았어 우리 통신하자! 그나저나 내 메세지도 잘 전달 될지 모르겠네? 너도 내 메세지를 정상적으로 받았다면 나한테 다시 알려줘~

  3. 클라이언트 : 메세지 잘 받았어! 이제 서로 통신이 잘 된다는 것을 알았으니 마음편히 통신하자 :smile:

이렇게 연결이 되고 나면 둘중 한 측이 close를 호출하여 연결을 끊을 때까지 연결이 계속 존재한다.

더 깊고 자세하고 세련되고 훌륭한 내용은 한재엽님의 좋은 자료를 참조하자.

TCP가 신뢰성있게 데이터를 송수신하는 원리

tcp헤더에는 sequence number와 ack가 있다. tcp를 통해 신뢰성 있는 전송을 하기 위해서는 sequence number와 ack가 상당히 중요하다.

  • Sequence Number : tcp는 애플리케이션(브라우저)에서 넘겨 받는 데이터가 크다면 이를 여러개의 패킷(세그먼트)으로 쪼개어 서버로 전송한다. 이때 세그먼트들의 순서를 의미하는 것이 sequence number라고 볼 수 있다. 예를 들어 3000byte 짜리 파일을 전송한다고 하자. 이때 한번에 보낼 수 있는 데이터가 100byte라면 tcp는 30개의 세그먼트로 쪼개어 서버로 전송할 것이다. 이럴 경우, 각 세그먼트의 sequence number field에 순서를 의미하는 번호를 붙인다. 1,2,3 이렇게 나타내는게 아니라 byte형식으로 나타낸다. 즉, 첫 번째 세그먼트가 0이라면, 두 번째는 100, 세 번째는 200. 이런 식으로 Sequence Number를 할당하여 서버측으로 함께 보낸다.

  • ACK : 받은 것에 대한 응답이다. 즉, 클라이언트에서 요청을 받은 후, 다시 클라이언트로 보내는 값이다. 어떤 값을 다시 클라이언트로 보낼까? 서버는 클라이언트로부터 앞으로 받아야 할 다음 데이터의 squence number를 ACK로 설정하고 보낸다. 즉, 클라이언트로 부터 sequence number가 0인 세그먼트를 받았다면, 서버는 이에 대한 응답으로 ack : 100 을 응답한다. 0번을 받았으니 이제 다음으로 받고 싶은 sequence number 100를 ack로 보내는 것이다.

이렇게 할 경우, 클라이언트 측이 서버로부터 받을 것이라고 기대했던 ack값이 오지 않을 경우 tcp가 다시 해당 세그먼트를 전송하기 때문에 신뢰가 있다. 자세히 들어가면 더 복잡한 방법으로 신뢰적이지만 여기서는 여기까지만 포스팅 하겠다.

NEXT

앞에서 언급했지만 결국 TCP도 IP에게 의뢰한다. TCP에 대해서 얕게 알아보았으니 IP에 대해서도 어느 정도 알아보겠다.

Comments