TCP 요청 client
와 응답 server
가 존재한다
TCP 통신 시, client(연결 시도하는곳)의 process가 통신을 위해 socket을 create/open 한다.
server(연결 응답하는곳)에서는 기본적으로 80번 port를 create/open 하여 연결 대기(listen)
한다.
즉, TCP에서는 상대의 port번호를 알야야 연결 시도를 할 수 있다. (L4의 식별자는 port이기 때문이다)
만일, server에서 요청 port를 열여두지 않은 상태라면, OS(kernel mode) 단에서 연결을 거부한다.
TCP protocol은 3-way handshaking을 통해 연결을 수립하고 4-way handshaking을 통해 해제한다.
3-way handshaking
: 세션을 수립하는 과정이며, 목적지와 수신지를 확실히 하여 데이터 전송의 신뢰성을 보장하기 위한 절차이다
RTT(Round Trip Time)
: 연결에 걸린 시간
sequence number와 정책(MSS 등의 정보)을 교환한다.
sequence number를 랜덤으로 생성
한다.sequence number를 랜덤으로 생성
하여 client의 sequence number에 1을 더한 값과 함께 응답한다.SYN
, ACK
의 통신은 Segment 단위로 한다. 이 segment는 일반적인 segment와 달리, payload 없이 ip 헤더와 tcp 헤더만으로 단순 통신이 이루어진다.
기본적으로 데이터 송수신은
분해 -> 전송 -> 조립
의 과정을 거친다.
분해는 송신 쪽에서, 조립은 수신 쪽에서 일어난다. 여기서의 분해란 Layer를 내려가며 데이터가 담기는 과정이기 때문에 Encapsulation
, 조립은 반대로 Layer를 올라가며 조립된 데이터를 Frame -> Packet ... 순으로 꺼내기 때문에 Decapsulation
이다.
분해라는 단어와 Encapsulation이라는 단어가 매치가 잘 안되지만, Segment를 여러개로 '분해'하여 Packet에 '담는(Encapsulation)' 과정이기 때문에 이렇게 부른다.
TCP는 연결지향적 프로토콜이기 때문에, 데이터(segment)를 성공적으로 수신할 경우 송신 측에 ack
를 보낸다. 예를 들어, data1, data2, data3... 를 보낸다고 하면, data2 까지 성공적으로 받을 경우 ack3 을 보내며, 이와 같은 과정들이 계속 반복된다.
지금까지 설명한 내용을 토대로 보면, 먼저 Process 시작된 데이터를 Stream을 통해 L4의 Socket에 write한다. 그리고 이를 Segment -> Packet으로 쪼개어 전송한다. 이때 TCP이기 때문에 각 패킷에 순서가 있는 번호가 매겨진다. 그 후, 패킷들은 L2의 Frame을 통해 목적지에 전달된다.
그리고 목적지에 도착한 후에는 이 과정이 역순으로 진행된다.
위에서 설명한 역순 과정인 데이터를 꺼내는 과정 중 마지막 단계는 아마 수신 측 Socket의 I/O Buffer에 각각의 Segment가 채워지고, 이 Buffer를 Process의 Buffer가 copy하여 읽는(receive) 과정일 것이다.
이때, 속도차
가 존재할 수 있다. 즉, 네트워크에서 지속적으로 쪼개진 데이터를 보내 Socket Buffer가 차는 속도와 Process에서 데이터를 copy하여 읽는 속도에 차이가 있을 수 있다.
Buffer는 크기가 제한되어 있기 때문에, Process가 읽는 속도가 Buffer가 차는 속도보다 현저히 떨어진다면 문제가 발생할 수 있다. 따라서 TCP에서는 ack와 함께 Buffer의 여유공간 등의 정보도 함께 보내어 오류를 방지한다.
ACK-Duplicate
일정 시간 이상 ack가 없을 경우, 송신 측에서는 re-transmission(재전송)을 한다. 이때, 시간 차로 re-transmission을 보내는 동시에 ack가 도착한다면, 수신 측에서는 이미 받은 데이터를 다시 받게 되는 문제가 발생
한다.
Out of Order
데이터의 순서가 잘못 오는 경우이다. ex) 1 - 3 - 2 -4
Zero Window
수신 Buffer의 여유 공간이 부족한 경우이다. (Buffer의 여유 공간의 크기를 Window Size라고 부른다).
이 경우는 대부분 Endpoint
, 즉 Application 단위
에서 데이터를 정상적인 속도로 copy하지 못하여 발생하는 경우가 많다.