[Network] TCP
CS/Network

[Network] TCP

1. TCP
2. TCP Segment
2.1. Segment 구조
3. TCP 연결 : 3-way-handshaking
4. 오류 제어 Error Control
4.1. checksum
4.2. 재전송 시나리오
4.1. TCP의 RTT 설정 방법
5. 흐름 제어 Flow Control
6. 혼잡 제어 Congestion Control
6.1. 혼잡 제어와 흐름 제어의 차이
6.2. CWND
6.3. 혼잡 제어의 동작

TCP

Transport Layer에 위치하고 있는 프로토콜입니다.

크게 다음과 같은 기능을 제공하고 있습니다.

  • 전이중 서비스
  • 흐름 제어
  • 오류 제어
  • 혼잡 제어
  • 연결 지향 서비스
  • 신뢰성 서비스
  • 세그먼트

TCP의 신뢰성 있는 전송을 위한 5가지 기법입니다.

  • Checksum 검사합
  • Ack, nAck 확인 응답
  • pipeline 동시에 여러개
  • seq. num 순서 번호
  • timer 타이머

Segment

TCP는 기본적으로 Process으로부터 내려오는 데이터를 각각 Buffer에다가 보관합니다.

이후 buffer에 있는 데이터 일부를 조합하여 Segment라는 Data Packet으로 만든 후에

IP 계층에 전달합니다.

 

이후 이 Segment들에게 각각의 순서 번호 1, 2, 3... 를 할당합니다.

TCP의 Segment 구조

Process로부터 발생된 데이터를 조합하여 만든 TCP만의 Packet 형식

Data 구조

Buffer로부터 가져온 데이터들로 구성되어 있습니다.
이들 바이트 데이터들은 각각의 번호를 가지고 있으며,
첫번째 바이트에 부여된 번호를 해당 Segment의 Sequence Number(순서 번호)로 지정합니다.

20~60 Bytes의 Header를 가지고 있습니다.

Header 구조

Source Port Address, Destination Port Address : 발신지와 도착지의 Process Port 번호
Sequence number(순서 번호) : segment에 포함된 데이터의 첫번째 바이트에 부여된 번호
Acknowledgement number(확인 응답 번호) : 잘 수신받았다고 응답, 수신받은 바이트 데이터 그 다음 번호를 보냄
Header Length(헤더 길이) : TCP 헤더 길이, 4Bytes의 Words 값으로 표현
Control : 제어 또는 flag
receive window : Server나 Client 자신이 받을 수 있는 최대 window 사이즈
checksum : 오류합으로 해당 segment가 제대로 되었는지 확인
Urg data pointer : 

Sequence Number 번호 매기는 방법

Buffer로부터 Byte Stream 몇개를 가져와서 조합하여 Segment를 만듭니다.

 

첫번째 Byte Number가 그림과 같이 100이라 가정했을 때

SYN은 Segment의 첫번째 바이트 스트림 번호인 100이 됩니다.

 

그리고 Server 측에서 해당 Segment를 정상적으로 받았다면

Segment 안에 있는 총 10개의 Bytes Stream을 받았다는 의미이므로

다음 Byte Stream 번호인 110이 ACK 번호가 됩니다.

잘 수신받았으니 다음 데이터를 가져와달라는 의미로 +1해서 보냅니다.

flag

  • urgent data
  • Ackknowledge : 응답
  • push
  • reset
  • Syncronization : 동기화 맺기 위한 모드, 연결을 시작할 때 쓰임
  • finish : 연결 종료할 때 쓰임

3-way-handshake에서 연결할 때 주로 

ACK과 SYN을 사용합니다.

나머지는 잘 사용하지 않습니다.


TCP 연결 : 3-way-handshaking

TCP는 앞으로 데이터를 주고받기 전에 우선 연결부터 진행해야 합니다.

연결 지향 서비스를 위하여 3-way-handshaking을 이용하여 연결합니다.

1. client는 Connection을 보내도 되냐는 SYN Packet을 보냅니다. 이때 SequenceNum은 x라 가정합니다.
2. Server측에서는 "연결해도 좋다"라는 OK 사인의 ACK Packet과 함께
Server측에서도 Client와의 연결을 위해 SYN Packet을 보냅니다.
이때 AckNum은 x+1로 SequenceNum은 새로운 숫자인 y로 설정됩니다.
3. Client측은 "연결해도 좋다"라는 OK 사인을 Server에게 보냅니다.
이때 AckNum은 y+1 입니다.

연결 종료 Closing a connection

연결을 종료하기 위해서 다음과 같은 단계를 거쳐야 합니다.

이때, Client, Server 각각의 상태들을 알고 있어야 합니다.

1. flag를 FIN으로 하고 Seq가 x인 패킷을 보냅니다.
지금까지 Client는 데이터를 보낼 수 없는 상태가 됩니다.
2. Server는 "Client는 연결 종료해도 좋다"는 메세지를 전달하기 위해 flag가 ACK이며 AckNUM이 x+1인 것을 보냅니다.
3. Client는 이제 서버가 close할 때까지 기다립니다.
4. Server 측에서 FIN, SeqNumy를 보냅니다.
이때부터 Server도 데이터를 보낼 수 없게 됩니다. 받을 순 있습니다.
5. Client는 "Server도 연결 종료해도 좋아"라는 메세지를 전달하기 위해 ACK, AckNumy+1을 보냅니다.
이때 Client는 서버가 종료되는 시점을 모르기 때문에 timed wait으로 대체합니다.
6. max segment lifetime의 2배정도를 기다린 후에 Client도 연결을 종료합니다.

 

부록 : Sender, Destination과 Client, Server는 어떤 차이?

Sender와 Destination은 종단과 종단의 느낌이였다면

Client, Server는 방향성 까지 고려하기 때문에 

Client가 Sender과 될 수 있고 Destination도 될 수 있습니다.

TCP에서는 Client, Server로 표현하는 것이 맞는 표현방식입니다.

부록 : TCP의 MTU는?

TCP는 Segment라는 단위를 사용하므로

MSS(Maximum Segment Size)라는 단어를 사용합니다.

MSS : 1420~1460Bytes

 

부록 : RDT, TCP ??

TCP는 기본적으로 RDT protocol에 기반한 protocol입니다.

RDT는 Sender Receiver에만 초점을 두었다면

TCP는 RDT를 양방향으로 사용하고 있다고 보면 될 것 같습니다.


오류 제어 Error Control

이제 TCP를 통해 1대1 연결을 하면 해당 파이프라인으로 데이터를 보냅니다.

그러나, 데이터를 보내는 과정에서 중간에 통신상태가 원활하지 않아

패킷이 훼손되거나 손실되었다면 어떻게 해야할까요?

 

TCP의 오류 발견 도구

  • checksum 검사합
  • Ack, Nack 확인응답
  • Timeout 시간 초과

TCP의 오류 복구(제어) 기법

  • Segment를 재전송하는 기법에 기초합니다.

 

checksum

데이터가 온전하게 잘 전달되었는지 무결성을 확인하는 기법입니다.

이를 통해 데이터가 훼손되었는지 확인이 가능하며 만일 checksum을 통해 훼손되었음이 검출되었다면

재전송을 요청합니다.

 

재전송 시나리오 Retransmission scenarios

Cumulative ACK은 말 그대로 번호가 축적되는 것을 의미합니다.

그래서 Server에서 100, 120, 140까지 받을 때 중간에 loss되어도

오류 재전송 이후 141부터 보내라고 할 수 있습니다.

 

Duplicate ACK은 번호가 반복되는 것을 의미합니다.

중간에 loss가 일어나도 pipeline으로 인해 Client가 계속 데이터를 보낼 때

중간에 에러난 ACK 번호를 계속 반복해서 보냅니다.

 

  • ACK이 delay되어서 sender에게 들어왔을 때 시나리오 - Cumulative ACK
Host A 입장에서는 RTT까지 기다렸지만 ACK이 오지 않아서 다시 Seq92부터 Segment를 보냈습니다.
Host B 입장에서는 이미 바이트 스트림 119까지 받아서 
다음에 오는 Seq92 Segment는 duplicate이기 때문에 제거하고
Host A에게 119까지 받아서 120을 보내달라는 ACK120을 보냅니다.
  • ACK이 중간에 loss 당했을 때 - Cumulative ACK
Host A 입장에서는 온전히 다 보냈지만 ACK이 중간에 깨져도
마지막 ACK이 120일 경우 Host A는 100을 보내지 않고
119까지 잘 받았으므로 ACK 120을 보냅니다.
  • Seq이 중간에 loss당해서 전달이 안됬을 때 시나리오 - Duplicate ACK
Host A는 pipeline 방식으로 한꺼번에 보내는데 중간에 Seq100 세그먼트가 loss되었습니다.
Host B 입장에서는 다음 ACK인 100이 안들어왔기 때문에 계속해서 ACK100을 보냅니다.
Host A 입장에서 만약 3번 이상 같은 ACK이 반복해서 온다면
timeout되기 전에 Seq100을 보내게 됩니다.
RTT만큼 기다리지 않고 바로 세그먼트를 다시 보냈습니다.
이를 TCP fest retransmit이라고 합니다.

흐름 제어 Flow Control

송신자의 TCP socket buffer가 overflow가 되지 않도록 해야합니다.

window 조절

RDT 프로토콜에 있는 Go-Back-N에서의 window 조절 방식을 이용합니다.
이미 Client로부터 온 데이터를 제외한 나머지 공간을 
rwnd(receive window)라고 표현하며
이는 TCP 3-way-handshake 연결할 때 미리 Client에게 '내가 처리할 수 있는 버퍼 크기'를 알려줍니다.

흐름을 통제하는 여러 기법들이 존재합니다.

  • Stop-and-wait
  • Go-Back-N (Sliding Window)
  • Selective Repeat

이들은 RDT 포스팅에서 자세히 다루었으니 이를 참고해주세요


혼잡 제어 Congestion Control

라우터에서 여러 방면으로 데이터가 들어오게 될텐데

각 traffic 마다 들어오는 속도 차이가 다를 것입니다.

한순간에 엄청나게 들어올 수 있기 때문에 언제 혼잡이 발생할지 모릅니다.

이를 위해 TCP에서는 혼잡 제어 알고리즘들을 사용하여 제어합니다.

 

혼잡 제어와 흐름 제어의 차이

흐름제어가 송신측과 수신측 사이의 전송속도를 다루는데 반해

혼잡제어는 호스트와 라우터를 포함한 보다 넓은 관점에서 전송 문제를 다룹니다.

 

혼잡 윈도우 Congestion Window CWND

RWND (Receive Window) : 수신자 윈도우 크기, flow control에서 나온 개념

CWND (Congestion Window) : 송신자 자신이 네트워크의 상황을 고려해서 정한 혼잡 윈도우 크기

이들 중에서 더 작은 값을 최종 window 크기로 정합니다.

혼잡 윈도우 처음 설정할 때

처음에는 혼잡 윈도우의 크기를 1 MSS로 정합니다.
1 MSS는 1460Bytes 이므로
1 CWND = 1 MSS = 1460 Bytes

이후 네트워크의 혼잡 상황을 유추하여 CWND의 크기를 조절합니다.

 

혼잡 제어의 동작

혼잡 제어를 위한 알고리즘들입니다.

  • slow start Algorithm 느린 출발 알고리즘
  • congestion avoidance Algorithm 혼잡회피 알고리즘
  • congestion detection algorithm 지수 감소 알고리즘
혼잡 회피 단계

1. Slow Start(느린 시작) : threshold(임계점)(window크기 반)(최초 임계점은 65535)를 설정하고 2^n 지수증가, 임계치에 도달할 때 까지 확인 응답이 오면 가산 증가
2. Congestion Avoidance(가산 증가) : 임계치에 도달하면 CWND 1씩 증가
3. Congestion Detection(지수 감소) : 혼잡 발생 시 임계치를 현재 윈도우 크기의 반으로 줄여서 다시 CWND 1로 느린시작

혼잡 상태라는 것을 2가지를 보고 알 수 있습니다.

  • Timeout
  • 3-duplicated-ACKs

2가지의 혼잡 상태 검출에 따라 Congestion Detection 방식이 다릅니다.

시나리오들을 보면서 살펴보겠습니다.

 

혼잡 제어의 다양한 시나리오들

  • Timeout
위의 혼잡 회피 단계와 동일합니다.
Time-out이 발생했을 경우에 지수 감소 단계에 돌입하게 되고
CWND를 1까지 뚝 떨어뜨리게 됩니다.
  • 3-duplicated-ACKs
3-duplicated-ACKs이 발생한 지점에서는
Timeout과는 다르게
threshold부터 시작하게 됩니다.
그래서 지수승으로 증가하는 것이 아닌, 가산 증가를 하게 됩니다.

 

TCP Taheo, Reno

Taheo는 1세대 TCP 버전으로써

혼잡 제어가 발생하면 무조껀 cwnd가 1로 초기화 됩니다.

 

Reno는 2세대 TCP 버전으로써

위에처럼 3-Duplicated-ACKs이 발생하면 cwnd가 임계점부터 시작하게 됩니다.

 

 


참조

대학교 네트워크프로토콜 강의

 

TCP/IP (흐름제어/혼잡제어) | 👨🏻‍💻 Tech Interview

최종 수정 : 10/3/2022, 1:23:47 PM

gyoogle.dev

 

'CS > Network' 카테고리의 다른 글

[Network] Application Layer  (0) 2022.12.08
[Network] RDT protocol와 Pipelined Protocol(Go-Back-N, Selective Repeat)  (0) 2022.11.24
[Network] UDP  (0) 2022.10.26
[Network] Transport Layer  (0) 2022.10.25
[Network] ICMP  (0) 2022.10.21