본 게시물은 이석복 교수님의 네트워크 강의를 수강하며 작성한 강의노트와 추가 공부한 내용을 바탕으로 작성하였습니다.
- 참고 강의 및 사이트
TCP : Connection-oriented transport
특징
- point-to-point
- reliable, in-order byte stream
- pipelined : window size를 가변적으로 설정(By Congestion control & flow control)
- send & receiver buffers : sender, receiver에 모두 버퍼 존재
- full duplex data : 양방향 데이터 통신
- connections-oriented : 데이터 통신 전, 3 way hand shake를 통해 connection 생성
- flow controlled : receiver나 네트워크가 받아들일 수 있는 만큼만 데이터 전달
TCP segment structure
Data 부분은 애플리케이션이 전달하고자 하는 Message가 들어가며 TCP는 Segment의 헤더를 보고 동작한다.
위는 헤더에 들어가는 항목들과 용량을 보여준다. 이 중, 현재 유의미하게 살펴볼 것들에 대해 간략히 알아보자.
포트번호는 16bit를 사용하므로 2^16 -1 개의 번호를 사용할 수 있다.
- source port number
- dest port number
- sequence number
- data부분에 나오는 첫 byte의 byte 순서 번호
- acknowledgment number(ACK)
- cumulative ACK : 10이라면 9까지는 다 받았다는 뜻으로, sender 입장에서는 10을 보낼 차례라는 의미이다.
- receive window : 수신자의 버퍼에 빈 공간이 얼마나 있는지를 알려준다.
- receiver buffer 의 byte 번호는 sender buffer의 번호와 동일하다.
- 즉 seq number는 sender buffer 상황에 따른 번호이며 ACK는 receiver buffer의 상황을 나타내는 번호를 의미한다.
실제 tcp는 500ms정도 기다렸다가 ack를 보내라고 권고
이유 1 ) cumulative ack 사용하기 때문
이유 2 ) 보낼 메시지가 생길 수도 있기 때문
Timeout - Fuction of RTT(Round Trip Time)
TCP의 타임 아웃을 어떻게 정할까?
RTT로 잡는다면 RTT 값이 모든 segment에 대해 고정된 값이라면 좋겠지만, 모든 segment마다 RTT값이 다 다르다. 지나는 경로가 다르고, 같은 라우터를 지나더라도 그 때마다 queue상황이 달라 queueing delay가 달라지기 때문이다. 너무 값이 다양하므로 대표할 수 있을 만한 SampleRTT값에 지금까지 축적되어온 값을 축적해서 구하여 판단한다.
(1-alpha)_EstimatedRTT + (alpha)_SampleRTT
실제 TCP는 500ms 정도 기다렸다가 ACK를 보내라고 권고한다. 그 이유는 Cumulative ACK를 사용하고, 추가로 보낼 메시지가 생길 수도 있기 때문이다.
TCP : Reliable Data Transfer
- Pipelined segments
- Cumulative acks
- single retransmission timer
- 타이머는 하나지만 expire되면 그 타이머가 expire되게 한 segment만 재전송한다.
타이머 시간은 마진 값을 더해놔서 타이머는 꽤 넉넉하다. 따라서 유실됐을 때 기다리고 있는 시간이 너무 길어지는 문제가 생길 수 있다. 하지만 타이머가 터지기 전 패킷 유실을 판단할 수도 있다.
- Fast Retransmit(빠른 재전송)
- 10에서 유실됐다면 receiver는 계속 ACK 10만 보내게 된다. 타이머가 터지기 전에 ACK 10이 계속 오게 된다면 10번째 segment가 유실됐다고 판단해서 타이머가 터지기 전에 미리 재전송하도록 하여 길어지는 대기시간 문제를 해결한다.
TCP : flow control
Sender가 Receiver의 용량을 고려하여 segment를 전달하는 것을 말한다. Receiver는 이를 위해 버퍼의 빈 공간에 대한 정보를 Segment 헤더에 담아 전달한다. Sender는 이를 보고 남은 공간만큼만 맞춰 데이터를 보낸다.
만약 receiver가 보내온 buffer-size 값이 0 이라면 어떻게 될까?
sender는 상대에게 공간이 생길 때까지 기다려야하지만 마냥 대기만 하고 있는다면, 빈 공간이 생겼어도 sender는 그 상황을 알 방법이 없다.
⇒ 따라서 TCP는 이런 상황에 주기적으로 segment를 receiver로 보내되, data부분은 없거나 아주 적은 양으로 보낸다. 그래야 receiver에게 공간이 생겼을 때 피드백을 받을 수 있기 때문이다.
TCP : connection management 3-way handshake
TCP의 sender와 receiver는 segment를 교환하기 위해 connection을 구축한다.
- TCP 통신을 위해 필요한 것
- seq numbers
- buffers, flow control info
- client : connection initiator
- server : contacted by client
Three way handshake
데이터가 왔다갔다 하는 것은 아니다. 데이터 교환은 연결 이후에 일어난다.
- client가 server에 연결 요청
- SYNbit = 1 , Seq = x ( SYNbit는 이 때만 1로 전달됨)
- server가 SYNACK 를 보냄 ( 이 이후부터는 SYNbit는 0)
- SYNbit =1, Seq = y, ACKbit = 1; ACKnum = x+1
- SYNACK에 대한 ACK를 보냄. 이 때부터 데이터 포함할 수 있음
- ACKbit=1, ACKnum=y+1
- 2가 아닌 3way handshake 인 이유?
- 서버 입장에서 확실히 연결됐는지 확인이 필요하므로 마지막 3단계를 시행한다.
- clinet가 살아있음을 확인하는 것이다.
Closing TCP Connection
- clientSocket.close();
- clinet가 FIN 보냄
- server는 보낼 ACK가 남으면 다 보낸 후 FIN을 보냄
- server가 FIN을 보낸 이후에도 몇 초동안은 기다리며 내가 보낼 데이터 혹은 상대방이 보낼 데이터를 주고받을 시간을 기다린다. ACK가 완전히 다 보내질 때까지 기다리는 것이다.
TCP Congestion Control (혼잡 제어)
네트워크 상황에 따라 TCP는 패킷을 보내는 속도를 조절해야 한다. 네트워크가 막힌다면 네트워크에 접속한 모두가 패킷을 전송할 수 없으므로 이를 방지하기 위해 TCP는 혼잡 제어를 통해 동작한다. 혼잡 제어란, TCP는 네트워크로부터 직접적인 피드백을 받을 수 없어 네트워크의 상황을 유추해서 전송할 패킷의 양을 조절하는 것을 의미한다. 비록 네트워크로부터 직접적인 피드백은 없으나 상대 리시버로부터의 피드백은 있기에 이를 통해 전송량을 결정하게 된다.
그렇다면 TCP는 어떤 방식으로 전송량을 결정하고 조절할까?
혼잡 제어 기법
- Slow Start
- AIMD
- Additive increase
- Multiplicative decrease
- Fast Retransmit
- Fast Recovery
위 세 가지 방식을 이해해보자.
먼저, 수로로 물을 보낸다고 생각해보자. 우리가 원하는 이상적인 상황은 보내는 물을 그대로 리시버가 모두 받는 것이다. 하지만 너무 많이 보내면 파이프가 터지는 문제가 발생하는데 파이프가 수용가능한 용량을 알 수 없다는 문제가 있다. 또한 파이프의 용량은 물이 이동하는 경로에 따라 다 달라서 더욱 알기 어렵다. 따라서 내가 보낸 물이 모두 가지 못하고 혼잡이 생기는 문제가 발생한다.
이런 문제를 방지하기 위해 물을 조금씩 보낸다면 어떻게 될까? 가장 얇은 파이프가 터지는 문제가 발생한다면 어떻게 될까?
이런 문제를 해결하기 위해 내가 보내는 물을 받는 쪽과 계속 정보를 교신하며 내부를 유추해나가야 한다. 여기서 파이프가 네트워크 상황, 보내는 물이 보내는 패킷, 이를 조절하는 방식이 TCP의 혼잡 제어라고 할 수 있다.
1. Slow Start
처음부터 물을 쏟아부으면 파이프가 터져버리는 위험이 있기 때문에 TCP는 조심스럽게 패킷을 보내기 시작한다. 이게 바로 슬로우 스타트다. 다만, 적은 양을 보내기로 시작해서 계속 천천히 보낸다면 통신을 마치는 데에 너무 많은 시간이 소요될 것이다. 따라서 슬로우 스타트는 비축 포인트를 증가시켜 2배씩 쭉쭉 그 양을 늘려나간다.
사실 시작하는 용량이 매우 작은 데에서 슬로우 스타트라는 이름이 붙었지만, 용량을 올려나가는 정도는 매우 기하급수적으로 빠르다. 아래서 다루는 AIMD 방식이 네트워크 수용량 주변에서는 효율적인 반면 처음 전송 속도를 올리는 데에 오래걸리는 단점을 Slow Start방식으로 극복할 수 있다.
다시 정리하자면 Slow Start 방식은 패킷을 하나씩 보내면서 시작하고, 패킷이 문제없이 도착하면 각각의 ACK 패킷마다 window size를 1씩 늘려준다. 즉, 한 주기가 지나면 window size가 2배로 된다.
2. AIMD
- Additive increase
계속 Slow Start 방식으로 많이씩 늘려나가다 보면 Threshold 지점에 도달하게 된다. 조심해야 하는 지점에 도달했다는 뜻이다. 따라서 이 순간부터는 Linear하게 증가하게 된다.
- Multiplicative decrease
계속해서 Window Size를 Linear하게 증가시켜나가다가 triple duplicate ACK가 발생하면 Threshold를 절반으로 줄이고 Window Size도 절반으로 줄인다. 네트워크 정체가 발생했다는 의미이므로 대폭 전송량을 줄여 네트워크 정체를 해결하는 것이다.
Threshold를 조정한 후 다시 linear하게 전송량을 증가시키는 것을 반복한다.
즉, 처음엔 아주 느린 속도로 보내되 굉장히 빠르게 Window Size를 증가시키다가(Slow Start), 어느 지점에 도달하면 증가 속도를 Linear하게 하고 패킷 유실이 발생되는 순간 Window Size를 절반으로 줄인 후 다시 Linear하게 전송한다.
TCP가 패킷 유실을 탐지하는 두 가지 상황을 고려해보자.
- Time Out
- 3 Duplicate ACK
위 두 상황은 동일하다고 볼 수 있을까? 위 두 상황에 대해 TCP가 동일한 대처를 하는 것이 효율적인 방식일까?
ACK가 중복으로 도착한 경우는 다른 패킷들은 잘 도착했으나 특정 한 패킷에서 문제가 발생한 상황을 의미하며 타임아웃이 발생하는 경우는 네트워크 정체가 심한 상황으로 볼 수 있다.
따라서 TCP는 타임아웃일 경우에는 아예 처음으로 돌아가서 Slow Start부터 시작하고 3Duplicate ACKs가 발생한 경우에는 Window Size만 절반으로 줄이는 방식으로 대처한다.
3. Fast Retransmit
3 Duplicated ACK를 통해 패킷 유실이 감지되면 타임아웃이 되기 전에도 패킷을 재전송한다.
4. Fast Recovery
혼잡 상태가 감지되면 윈도우 크기를 1로 줄이지 않고 반으로 줄이는 방식이다.
이런 방식으로 통신량을 조절하면 TCP 개개인들에게 형평성을 보장할 것인가?
- 먼저 사용하던 사람이 처음엔 높은 속도를 가질 수 있다.
- 이후에 들어온 TCP가 생겨 네트워크 혼잡이 발생하면, Multiplicative decrease를 통해 모두가 윈도우 사이즈를 반으로 줄이게 되며 이 과정이 반복되다보면 결국 공평해지는 결과를 얻을 수 있다.
- 단, 이는 TCP 각각에게 공평한 것으로 사용자 단위로 TCP Connection을 많이 여는 사용자가 더 많은 통신량을 가져간다는 맹점이 존재한다.
혼잡 제어 정책
혼합 제어 정책 중 대표적인 아래 두 정책에 대해 살펴보겠다.
- Tahoe
- Reno
이 외에도 New Reno, Cubic, Ealstic-TCP 까지 다양한 혼합 제어 정책이 존재한다.
TCP Tahoe
처음엔 Slow Start를 사용해 자신의 윈도우 크기를 지수적으로 증가시키다가 임계점(Threshold)을 만나면 AIMD를 사용하여 선형적으로 윈도우 크기를 증가시킨다. 그러다 3 Duplicated ACK나 Timeout 발생 시 네트워크 혼잡이라 판단하여 Threshold와 윈도우 크기를 수정하는 방식이다.
이 방식은 혼잡 상황이 발생한 지점을 기억해 그 지점에 가까워지지 않기 위해 조절하지만 초반 Slow Start 구간에 윈도우 크기를 늘릴 때 오래 걸린다는 것과 혼잡 상황에서 항상 윈도우 크기를 1에서부터 다시 시작한다는 단점이 있다.
TCP Reno
Tahoe 이후 나온 정책이다. 마찬가지로 Slow start로 시작하여 임계점을 넘으면 AIMD 방식을 사용한다. 다만, 앞에서 설명한 3 Duplicated ACK와 Timeout을 구분하여 대응한다.
'Learning-log -CS > Network' 카테고리의 다른 글
(컴퓨터와 네트워크) 네트워크 계층 - 라우터 알고리즘(Link State, Distance Vector) (1) | 2024.02.25 |
---|---|
(컴퓨터와 네트워크) 네트워크 계층(IP, DHCP, ICMP) (1) | 2024.02.15 |
(컴퓨터와 네트워크) 전송 계층 (기능, UDP, RDT의 원리) (1) | 2024.01.22 |
(컴퓨터와 네트워크) 네트워크 계층, 애플리케이션 계층(Application Layer) (0) | 2024.01.21 |
(컴퓨터와 네트워크) 네트워크 구조 (2) | 2024.01.03 |