-
TCP ( Transmission Control Protocol )Computer Science 2023. 12. 1. 00:03
TCP ( Transmission Control Protocol )
Transmission : 전송
Control : 제어
Protocol : 프로토콜 ( 통신 규약 )
OSI 7 Layer에서 Transport Layer ( 4계층 )을 사용하는 프로토콜로 3계층에서 사용하는 IP와 같이 묶어서 TCP/IP라고 많이 부릅니다.
TCP란
TCP는 세그먼트 단위로 데이터 통신을 하기 위한 프로토콜이며 다음과 같은 특징을 가지고 있습니다.
1. 연결 지향적
TCP는 통신을 시작하기 전에 3-way handshake 방식으로 연결을 설정하고, 통신을 종료할때 4-way handshake 방식으로 연결을 종료합니다.
2. 신뢰성 있는 통신
TCP는 데이터 세그먼트의 순서, 손실을 관리하여 데이터가 정확하게 수신되도록 통신합니다. 이것이 가능하도록 TCP는 각 세그먼트에 순서 번호를 할당하고 수신자는 받은 세그먼트에 대해 확인 응답(ACK)를 보냅니다.
3. 전이중, 점대점 통신
TCP는 전이중 통신 ( 하나의 연결에 송수신이 동시에 가능 ) 이 가능하며, 점대점 방식 ( 하나의 연결은 정확히 2개의 종단점을 가짐 ) 으로 통신합니다.
4. 흐름 제어 ( Flow Control ) 과 혼잡 제어 ( Congestion Control )
흐름 제어와 혼합 제어를 통해 효율적인 데이터 전송을 합니다.
위 방식들에 대해 좀 더 자세히 알아보면 다음과 같습니다.
3-way handshake
SYN : Syncronize 의 약자로 "동기화"로 생각하면 됩니다.
ACK : Acknowledgment 의 약자로 "승인"으로 생각하면 됩니다.
명칭부터 3-way handshake이니 총 3번 통신이 발생합니다.
1. Client 측에서 Server 측에 SYN 패킷을 보내는데 이때 랜덤으로 생성한 Sequence Number를 담아 보냅니다.
2. Server 측은 수신한 Sequence Number에 1을 더하고 ACK 패킷을 Client에 보내는데 이때 SYN 또한 활성화 하여 보냅니다. 즉 ACK + SYN 패킷을 수신한 Sequence Number에 1을 더해 함께 보냅니다.
3. Client는 수신한 패킷의 Sequence Number가 자신이 보낸 것에 1 더해진 값이 맞는지 확인하고 정상이라면 Server에게 다시 ACK 패킷을 보냅니다. 서버가 이를 수신하면 연결이 완료된 상태입니다.
4-way handshake
FIN : Finish의 약자로 "끝"으로 생각하면 됩니다.
3-way handshake와 마찬가지로 명칭이 4-way handshake이니 총 4번 통신이 발생합니다.
1. Client 측에서 통신을 종료하겠다는 의미인 FIN 패킷을 Server 측에 보냅니다.
2. Server 측은 FIN 패킷을 수신하면 우선 알겠다는 의미로 ACK 패킷을 보냅니다.
3. 그 후 Server 측에서 FIN 패킷을 보내는데 만약 보낼 데이터가 남아 있다면 해당 데이터를 전부 보낸 다음 FIN 패킷을 보냅니다.
4. Client 측은 FIN 패킷을 받으면 확인했다는 의미로 ACK 패킷을 다시 Server 에 보냅니다. 이제 연결이 종료됩니다.
연결 후 통신 방식
연결이 성립된 후에는 이제 데이터를 주고 받아야합니다. 예를들어 Server 측에서 Client에게 데이터를 보낸다고 가정한다면 다음과 같은 과정을 거칩니다.
1. Application (Server) 이 데이터를 보내려고합니다. 해당 데이터를 보내기 위해 Socket Api 를 이용하여 Transport 계층으로 데이터를 내려보냅니다.
2. Transport 계층 ( TCP ) 는 해당 데이터를 받아 쪼개서 Segment 단위로 만들고 번호를 붙입니다. 그후 각 Segment를 Network 계층으로 내려보냅니다.
3. Network 계층은 받은 Segment 데이터를 Packet으로 변환하고 DataLink 계층으로 내려보내며 이때 Frame으로 변환합니다.
4. 해당 Frame은 Client까지 가게되고 Client는 해당 패킷을 받아 Transport 계층 ( TCP ) 까지 오게 됩니다. 올바른 Segment라면 Buffer에 담게 되고 잘 받았다고 Server에게 ACK를 해당 Segment 번호와 함께 보냅니다.
5. Server는 ACK를 받으면 다음 Segment를 전송합니다.
흐름 제어 ( Flow Control )
Sliding Window - 수신자가 처리할 수 있는 데이터의 양을 조절하여 Buffer Overflow를 방지하는 방식입니다.
위 과정에서 4,5를 진행함에 있어 1개씩 전송하면 매우 비효율적일 것입니다. 특히 TCP가 느린 이유중 가장 큰 원인은 해당 Segment를 보내고 ACK를 받기까지 Wait하고 있기 때문입니다. 하여 TCP는 4번과정에서 여러 Segment를 한번에 보내는데 이를 가능하게 하려면 Client 측의 Buffer 크기를 알아야합니다.
Client의 Buffer 보다 크게 보낸다면 Client는 해당 데이터를 전부 수신하지 못할 테고 이로인해 낭비가 크기 때문입니다. 따라서 Client는 Server 측에 남은 Buffer 크기 즉 Window Size를 보내줍니다. 그 크기를 확인하고 서버는 해당 크기에 알맞게 데이터를 보내게 됩니다.
초기 Window Size는 3-way handshake를 하는 중에 바로 보내줍니다. 즉 처음 SYN 과정에서 보내줍니다. 그 다음부터는 4번과정인 Server에 ACK를 보낼때 함께 보냅니다.
이렇게 Window Size가 확정된 후에는 각 Segment 를 보내고 ACK가 도착한다면 다음 패킷을 보내면 됩니다. 이것이 Window 가 점차 움직이는 것 처럼 보이기에 Sliding Window 라고 부릅니다.
혼잡 제어 ( Congestion Control )
Client가 수신할 수 있는 양과는 별개로 네트워크가 데이터를 감당하지 못할 수 있습니다. 특정 라우터에 데이터가 몰릴 경우, 해당 데이터를 모두 처리 할 수 없고 이로 인해 재전송이 발생하는 등 혼잡도가 증가하게 됩니다.
이러한 경우를 해결하기위해 송신하는 쪽에서 데이터의 전송속도를 조절하게 되는데 이 과정을 혼잡 제어라고 합니다. 혼잡 제어를 하는 방식은 여러가지가 있는데 다음과 같습니다.
AIMD ( Additive Increase / Multiplicative Decrease )
해석하면 "합 증가 / 곱 감소"로 말 그대로 선형적으로 증가하다 절반으로 감소하는 형태입니다. 초기에 Client에게 보내는 패킷 수를 1개씩 늘려가다가 전송이 실패하거나 일정시간 응답이 없다면 보내는 패킷 수를 절반으로 감소하는 방식입니다.
이 방식의 문제점은 초기부터 높은 전송 속도를 가질 수 없고, 네트워크가 혼잡해지고 나서야 대역폭이 줄기 때문에 혼잡해지는 상황을 미리 감지하지는 못한다는 것입니다.
Slow Start ( 느린 시작 )
느린 시작 방식은 AIMD 처럼 패킷을 초기에 1개씩 보내지만 성공적으로 ACK 가 수신된다면 수신된 만큼 Window Size 를 증가시키는 방법입니다. 즉 처음에 1개를 보내고 ACK개 1개 수신된다면 그다음은 2개를 보내고 2개의 ACK가 수신된다면 다음 4개를 보내는 방식으로 AIMD의 방식과 다르게 지수 함수 형태로 전송 속도가 증가하게 됩니다. 다만 전송 실패 시 ( Timeout ) AIMD 처럼 절반으로 떨어뜨리는 것이 아닌 창의 크기를 1로 떨어뜨립니다.
Fast Recovery ( 빠른 회복 )
네트워크에서 패킷 손실이 감지되면 윈도우 크기를 1로 줄이는 것이 아닌 절반으로 줄이는 것입니다.
보통 중복된 ACK 등 일부 패킷 손실 시에 Fast Recovery 를 진행하며 Timeout ( 타임아웃 )이 발생하면 Window Size를 1로 변경합니다.
ACK 가 중복이 일어났다는 것은 도착해야할 패킷보다 이후의 패킷이 먼저 도착했다는 의미입니다. 예를들어 1,2,3,4 를 전송했는데 도중 3이 사라졌다면 Client는 ACK 2,3을 전송하고 4가 왔을때에도 ACK 3을 전송하게 됩니다. 타임아웃은 설정된 시간내에 어떠한 ACK도 오지 않았을 때 발생합니다.
Congestion Avoidance ( 혼잡 회피 )
네트워크의 혼잡을 감지하면 전송률 증가를 늦추고, 순차적으로 증가시킵니다 ( AIMD 방식 ). 즉 Slow Start 이후에 특정 크기까지 전송 속도가 커진다면 이후로는 지수적으로 증가하는 것이 아닌 선형적으로 증가하는 형태로 변경합니다. 이 특정 크기는 ssthresh ( Slow Start Threshold ) 로 Slow Start와 Congestion Avoidance의 임계값이 됩니다.
Fast Retransmit ( 빠른 재전송 )
ACK의 중복이 발생했다는 것은 해당 패킷이 손실되었다는 것을 의미합니다. Fast Retransmit은 중복이 3번 반복 ( default ) 되면 해당 패킷의 ACK를 Timeout 될때까지 기다리는 것이 아니라 바로 재전송을 합니다. 물론 중복이 발생했기에 Fast Recovery 또한 진행됩니다.
즉 전체 혼잡 제어 기능을 살펴보면 다음과 같습니다.
1. Slow Start
2. ssthresh 만큼 Window Size가 커진다면 그 이후로는 Congestion Avoidance.
3. 통신 도중 패킷 손실 등 ACK 중복 발생시 Fast Recovery 만약 3회 이상이라면 Fast Retransmit 진행.
4. 통신 도중 TimeOut 발생시 Window Size 1로 변경
'Computer Science' 카테고리의 다른 글
[TypeScript] Type Compatibility ( 타입 호환성 ) (1) 2023.12.09 [JavaScript] Object VS Map ( 성능 비교 ) (1) 2023.12.02 OSI model ( OSI 7 Layer ) (0) 2023.11.28 Git ( Rebase, Squash ) (0) 2023.11.07 Spin Lock vs Mutex vs Semaphore (0) 2023.09.18