TCP는 오류 검출, 재전송, 누적 확인응답, 타이머, 순서 번호, 확인응답 번호를 위한 헤더 필드를 가지고 있다.
A) TCP Connection
Connection-oriented: TCP Application process끼리 데이터를 주고받기 전에, 두 process가 서로 Handshake를 해야 한다.
TCP Connection: 두 End system의 TCP에 존재하는 상태를 공유하는 논리적인 것으로, End system간의 TCP 연결만 유지되며 중간의 Network core들은 TCP 연결 상태를 유지하지 않는다.
TCP 특징
-
Full-duplex service: Application layer message는 Host A에서 Host B로 흐르는 동시에 A에서 B로도 흐를 수 있다.
-
Point-to-point: 항상 단일 송신자에서 단일 수신자로만 데이터 전송이 가능하다.
TCP 연결 설정 (Three-way handshake)
한 Host에서 동작하는 프로세스가 다른 Host와의 연결을 초기화하기를 원한다고 가정하자.
Client process: 연결을 초기화하는 process
Server process: 다른 process
-
Client process는 Server process와 연결을 설정하기를 원한다고 TCP client에게 먼저 알린다.
- Client의 Transport layer에서 특별한 TCP segment를 전송한다.
-
Server는 두 번째 특별한 TCP Segment로 응답한다.
-
Client가 세 번째 특별한 Segment로 다시 응답한다.
(1), (2)의 segment에는 payload (즉, Application layer message) 가 없다.
(3)의 Segment는 payload를 포함할 수 있다.
TCP 데이터 전송
Three-way handshake가 이루어지면, 두 application process는 서로 데이터를 보낼 수 있다.

-
Client process는 socket을 통해 데이터 스트림을 전달하고 TCP는 데이터를 Send buffer로 보낸다.
- 이 과정에서 TCP는 Segment로 데이터를 묶어 보낼 수 있다.
- TCP Segment: TCP Header + client data
- 최대 데이터의 양은 MSS(Maximum Segment Size)로 제한된다.

-
Segment 처리 이후, Network layer에 전달되며, Network layer IP datagram안에 캡슐화된다.
-
Datagram은 Network로 송신되며, TCP가 상대에게세 Segment를 수신한다면 해당 Segment는 TCP Receive buffer에 위치한다.
-
Application은 Receive buffer로부터 데이터 스트림을 읽는다.
B) TCP Segment structure
TCP Segment는 Header field, Data field 로 구성되어 있다.

1. Data field
- Application data의 일정량을 담는다.
- MSS에 의해 data field의 크기가 제한될 수 있다.
- Source / Destination port number
- Multiplexing / Demultiplexing에 사용한다.
- Checksum field
- 32 bit sqeunce number field & 32 bit acknowledgment number field
- Reliable data transmission에 사용한다.
- 16 bit receive window field
- Congestion control에 사용한다.
- 4 bit header length field
- 이 field로 표현하는 것은 실제로 32 bit (4 byte) 단위이다.
- 4 bit header length: 1 이라면 실제 길이는 4 byte이다.
- option field로 인해 가변적인 길이가 될 수 있다.
- Option field
- MSS 협상, window 확장 등에 사용한다.
- 6 bit flag field
- ACK bit: Acknowledgment number field의 값이 유용함을 가리킨다.
- RST / SYN / FIN bit: 연결 설정과 해제에 사용한다.
- PSH bit: 수신자가 데이터를 상위 계층에 즉시 전달해야함을 가리킨다.
- URG bit: 송신 측 상위 계층 개체가 ""Urgent""로 표시하는 데이터임을 가리킨다.
- 이때, 데이터의 마지막 byte의 위치는 16 bit urgent data pointer field에 의해 가리켜진다.
Sequence number & Acknowledgment number
TCP의 Reliable data transfer에 가장 중요한 field이다.

TCP가 Sequence number field를 채우는 방법
전제: TCP는 데이터를 구조화되지 않고 단지 순서대로 정렬되어 있는 바이트 스트림으로 본다.
- 송신 Host는 데이트 스트림의 총 Byte를 MSS의 크기로 나누어 segment를 구성한다.
- 각 Segment마다 Sequence number는 해당 Segment에존재하는 첫 번째 바이트의 바이트 스트림 번호이다.
위의 그림에서 두 번째 segment의 sequence number는 1000이다.
TCP가 Acknowledgment number field를 채우는 방법
전제: TCP는 Full-duplex service이다.
- 수신 Host는 송신 Host로부터 기대하는다음 바이트의 Sequence number를 Acknowledgment number field에 삽입한다.
Cumulative acknowledgment: TCP는 스트림에서 잃어버린 바이트까지의 바이트들까지만 확인 응답한다.
- EX) 수신 호스트가 0~555 까지의 바이트와 900~1000의 바이트를 수신했을 때, Acknowledgment number는 556이다.
- 이 경우, 수신자는 순서가 바뀐 segment를 즉시 버리거나, buffer에 중간 바이트가 도착할 때까지 저장할 수도 있다.
- Cumulative acknowledgment number - 1 byte까지는 수신했다는 의미를 내포한다.
C) RTT expectation & Timeout
Timeout은 데이터를 보내고 acknowledgment packet을 받는 RTT보다 조금 더 커야 한다.
RTT expectation
SampleRTT: Segment가 송신된 시간으로부터 그 Segment에 대한 긍정 응답이 도착한 시간 길이
- TCP는 송신 후 아직 확인 응답이 없는 Segment 중 한 번에 하나의 Segment의 SampleRTT 측정만을 시행한다.
- 재전송한 segment에 대한 SampleRTT는 계산하지 않는다.
- 불안정성으로 인해 Segment 마다 값의 차이가 발생한다.
EsimatedRTT: 불규칙적인 SampleRTT 대신 RTT를 추정하기 위해 사용하는 SampleRTT의 평균값
- 새로운 SampleRTT를 획득하자마자 EstimatedRTT를 갱신한다.
- EstimatedRTT = (1 - α) ⋅ EstimatedRTT + α ⋅ SampleRTT
- α = 0.125 가 권장되는 값이다.
- SampleRTT 값의 Weighted average이다.
DevRTT: RTT의 변화율
- SampleRT가 EstimatedRTT로부터 얼마나 많이 벗어나는지에 대한 예측
- DevRTT = (1 - β) ⋅ DevRTT + β ⋅ |SampleRTT - EstimatedRTT|
- β = 0.25 가 권장되는 값이다.
Exponential weighted moving average: Estimated에서의 SampleRTT와 DevRTT에서의 |SampleRTT - EstimatedRTT|
- 두 값은 값이 갱신될 수록 가중치가 빠르게 지수적으로 감소한다.
재전송 타임아웃 주기의 설정과 관리
Timeout은 EstimatedRTT에 약간의 여윳값을 더한 값으로 설정하는 것이 좋다.
- Timeout은 EstimatedRTT보다 반드시 크거나 같아야 한다.
- 너무 크다면 즉각적인 재전송이 불가능하기 때문에 안 된다.
- SampleRTT의 변동이 많다면 여윳값을 크게 하고, 아니라면 여윳값을 작게 한다.
TimeoutInterval = EstimatedRTT + 4 ⋅ DevRTT
- EstimatedRTT가 수정되면 TimeoutInterval을 위 공식에 따라 다시 계산한다.
- 초기 TimeoutInterval은 1초가 권장된다.
D) Reliable Data Transfer
TCP는 Reliable data transfer service를 제공한다.
- Receive buffer로부터 읽은 byte stream이 손상되지 않았으며 손실이나 중복이 없고, 순서가 유지된다는 것을 보장한다.
- TCP protocol은 확인 응답되지 않은 Segment 중 하나에만 동작하는 단일 재전송 타이머를 사용한다.
TCP의 Reliable data transfer service 과정
TCP 송신자 측은 세 가지의 주요 Event를 가지고 있다.
-
상위 Application으로부터 데이터 수신
- 데이터를 받고, Segment로 캡슐화한 후 IP에게 전달한다.
- Timer가 다른 Segment에 대해 실행 중이 아니면, TCP는 Timer를 시작한다.
-
Timer timeout
- Timeout event가 발생하면 송신자는 Timeout을 일으킨 Segment를 재전송하고 TCP의 Timer를 다시 시작한다.
-
ACK 수신
- SendBase(수신 확인응답이 확인되지 않은 가장 오래된 바이트의 Sequence number) 와 ACK의 값을 (y라고 하자) 비교한다.
- y > SendBase: ACK는 이전에 확인 응답이 되지 않은 하나 이상의 Segment를 확인하고 송신자는 자신의 SendBase의 값을 갱신한다.
TCP Data transfer의 세 가지 가능성
- ACK Packet loss

- ACK Paket이 손실되면, Host A는 Data를 재전송할 것이다.
- Host B가 재전송 Segment를 수신했을 때, Host B는 이미 수신된 데이터임을 확인하고 버릴 것이다.
- 두 개의 Data packet에 대한 어떠한 ACK도 받지 못한 경우

- Timeout 이전에 Sequence number 92에 대한 ACK를 받지 못하였기 때문에 Sequence number 92 packet을 재전송하고 타이머를 다시 시작한다.
- 재전송된 Segment에 대해 Host B는 이미 모든 데이터를 수신했으므로 ACK = 120 을 전송한다.
- 첫 번째 Segment에 대한 Timer 동안 두 번째 Segment에 대한 ACK가 도착한 경우

- 첫 번째 ACK Packet은 손실됬지만 두 번째 ACK Packet은 시간 내에 도착했다.
- TCP는 로이기 때문에 두 번째 ACK Packet만으로도 첫 번째 Data를 수신했음을 확인할 수 있다.
TCP 구현에서 사용하는 몇 가지 수정사항
1. Timeout Interval
- TCP는 Timeout이 발생할 때, 아직 확인 응답이 되지 않은 가장 작은 Sequence number를 가진 Segment를 재전송한다.
- 이때, TCP는 단순하게 Timeout Interval을 2배 증가시킨다.
- 재전송이 아닌 다른 Event인 경우에는 DevRTT, EstimatedRTT로 부터 TimeInterval을 계산하여 사용한다.
2. Fast Retransmit
- 재전송 시 Timeout Interval을 2배씩 증가시키기 때문에, Timeout Inteval이 너무 커져 빠른 재전송이 불가능할 수 있다.
- Duplicate ACK: 송신자가 이미 이전에 받은 확인 응답에 대한 재확인응답 Segment ACK
- 수신자가 여러 개의 Data를 전송하였을 때, 중간에 하나의 Packet이 손실되었다면 같은 ACK가 여러개 수신될 수 있다.

- 2번째 packet이 손실되어 3개의 Duplicate ACK가 수신되었다.
- Fast Retransmit: 송신자는 Timeout 이전에 손실 Segment를 재전송하였다.
Q) TCP는 GBN인가 SR인가?
TCP는 GBN과 SR protocol의 혼합이다.
GBN과 유사하다?
- TCP는 순서가 잘못된 segment는 개별적으로 ACK를 받지 않는다.
- 송신자는 SendBase 와 NextSeqNum을 유지해야한다는 점에서 GBN과 유사해 보인다.
GBN과의 차이점
송신자가 1, 2, ..., N Segment를 전송하고, 1, ... , n Segment만이 ACK되었다고 가정하자.
- GBN: n, n+1, ..., N 의 모든 Segment를 재전송한다.
- TCP: n Segment만을 재전송하고, 만약 Timeout 이전에 n+1 ACK가 도착한다면 재전송조차 하지 않는다.
Selective acknowledgment: 수신자가 마지막으로 올바르게 수신된 Segment에 대해 Cumulative acknowledgment을 하기 보다는 순서가 틀린 segment에 대해 선택적으로 확인 응답을 하게 한다.
- 이것은 오히려 SR protocol과 유사하다.
- 이 관점에서, TCP는 GBN과 SR protocol의 혼합이라고 할 수 있다.
E) Flow Control
Receive buffer에 저장된 data를 Application이 바로 읽지 않으면 데이터가 쌓여 Receive buffer에 overflow가 발생할 수 있다.
해결책: TCP Flow-control service
송신자의 데이터 전송 속도 = 수신자의 데이터 리딩 속도을 유지하도록 하는 서비스
- 송신자가 수신자의 Buffer를 Overflow시키는 것을 방지하기 위해 사용한다.
- IP Network에서의 혼잡을 제어하는 Congestion control과는 다른 것이다.
TCP 수신자가 순서가 바뀐 Segment는 버린다고 가정하자.
Flow control 세팅
할당된 Receive buffer size를 RcvBuffer라고 하자

-
송신자는 수신 측에서 가용한 Buffer space가 얼마나 되는지 송신자에게 알려주는 Receive window라는 변수를 유지한다.
- TCP는 Full-duplex이므로 각 측의 송신자는 별개의 Receive window를 유지한다.
-
수신자의 Application process는 Buffer로부터 데이터를 읽으며 LastByteRead와 LastBtyeRcvd 변수를 세팅한다.
- LastByteRead: Host B의 Application process에 의해 Buffer로부터 읽힌 데이터 스트림의 마지막 byte number
- LastBtyeRcvd: Host B의 Receive Buffer에 저장된 데이터 스트림의 마지막 byte number
- TCP는 할당된 Buffer의 Overflow를 허용하지 않는다.
- RcvBuffer ≥ LastByteRcvd - LastByteRead
-
rwnd라는 변수를 Update되는 다른 변수에 맞게 변경한다.
- rwnd: Buffer의 여유 공간
- rwnd = RcvBuffer - {LastByteRcvd - LastByteRead}
Flow control 방법
-
Host B는 Host A에 전송하는 모든 Segment의 Window field에 현재의 rwnd 값을 설정한다.
-
Host A는 LastByteSent와 LastByteAcked를 유지한다.
- {LastByteSent - LastByteAcked}는 Host A가 해당 연결에 전송 확인 응답이 되지 않은 데이터의 양이다.
-
(1), (2)의 과정에서 전송 확인 응답이 되지 않은 데이터의 양이 rwnd보다 작다면 Overflow가 발생하지 않음을 확신할 수 있다.
- rwnd ≥ LastByteSent - LastByteAcked
문제점
Host B의 rwnd = 0이고 Host A에게 전송할 것이 없다고 가정하자.
-
Host B의 Buffer가 비워지더라도 TCP는 Host A에게 새로운 rwnd로 segment를 전송하지 않는다.
-
Host A는 Host B의 buffer에 여유 공간이 있다는 것을 알 수 없기 때문에 데이터를 더 이상 전송될 수 없다.
이런 문제를 해결하기 위해, TCP는 Host A와 Host B의 receive window가 0일 때, 1 byte data로 segment를 계속하여 전송하도록 요구한다.
- 1 byte segment는 수신자에 의해 긍정 확인 응답되고, 이 긍정 확인 응답은 0이 아닌 rwnd 값을 포함한다.
F) TCP connection 관리
TCP conncetion setting - Three-way handshake

-
Client TCP는 Server TCP에게 Application data를 포함하지 않지만 SYN bit (flag bit) = 1인 Segment를 전송한다.
- 이 Segment를 SYN segment라고 한다.
- 클라이언트는 최소 순서 번호(client_isn)를 임의로 선택하고, 최초의 TCP SYN 세그먼트의 순서 번호 필드에 이 번호를 넣는다.
-
SYN segment가 Server host에 도착하면 Server는 SYN segment를 추출하고 TCP buffer와 변수를 할당한다. 이후, 연결 승인 segment를 송신한다.
- 연결 승인 segment에는 Application data를 포함하지 않고, SYN bit = 1, Acknowledgment field = client_isn + 1로 설정한다.
- Server는 자신의 최초의 server_isn (순서 번호)를 선택하고 Header의 Sequence number field에 이 값을 넣는다.
- SYNACK segment라고 불린다.
-
SYNACK segment를 수신하면, Client는 TCP buffer와 변수를 할당하고, SYNACK segment를 확인하는 또 다른 Segment를 송신한다.
- Acknowledgment field = server_isn + 1 값을 넣음으로써 SYNACK segment를 확인한다.
- 이 단계에서는 Application data를 Segment payload에 포함할 수 있다.
- 이 Segment부터 시작하여, 이후 전송되는 Segment의 SYN bit = 0이다.
TCP Connection Close
TCP Connection이 종료될 때, Host의 자원 (Buffer, Variable)은 회수된다.
Client가 연결 종료를 결정한다고 가정하자.

-
Client process는 종료 명령을 내리고, Server process에 FIN bit = 1을 header에 포함하는 특별한 TCP Segment를 보내도록 한다.
-
Server가 이 Segment를 수신하면, Server는 Client에게 Acknowledgment Segment를 보낸다.
-
이후 Server는 FIN bit = 1로 설정된 자신의 종료 Segment를 송신한다.
-
Client는 Server의 종료 Segment의 Acknowledgment Segment를 보낸다.
(4)의 시점에서, 두 Host의 모든 자원을 할당 해제된다.
TCP Connection State
Client와 Server로 나누어 살펴보자.
TCP Client

TCP Connection Setting
1. Closed: Closed 상태에서 시작한다.
2. SYN_SENT: SYN segment를 전송하며 TCP Connection을 시작한다.
3. ESTABLISHED: Server로부터 SYN, ACK segment를 수신한 후의 상태
TCP Connection Close
4. FIN_WAIT_1: FIN bit = 1을 포함하는 TCP segment를 송신한 상태
5. FIN_WAIT_2: Server로부터 확인응답을 포함하는 Segment를 받은 상태
6. TIME_WAIT: Server로부터 FIN bit = 1을 포함하는 Segment를 받고, Server에 확인 응답으 전송한 후에 상태
- 대기 시간이 종료되면 연결이 정식으로 종료되고, Client 측의 모든 자원이 해제된다.
TCP Server

TCP Connection Setting
1. Closed: Closed 상태에서 시작한다.
2. LISTEN: Client로부터 SYN segment를 수신하고, SYN과 ACK segment를 송신한다.
3. ESTABLISHED: Client로부터 ACK segment를 수신한 후의 상태
TCP Connection Close
4. ESTABLISHED: Client로부터 FIN segment를 받고, ACK Segment를 송신한다.
5. CLOSE_WAIT: FIN bit = 1 segment를 송신한다.
6. LAST_ACK: Client로부터 ACK Segment를 받고, 연결을 종료한다.
Q) 만약 어떠한 Socket과 관계없는 Port number와 IP address를 가진 TCP segment를 수신한다면?
수신 Host는 송신 Host로 RST Flag bit = 1로 설정된 Reset segment를 보낸다.