강의 링크 :http://www.kocw.net/home/cview.do?mty=p&kemId=1169634
flow control
TCP
의 중요한 기능 중 하나인 flot control
은 sender
와 receiver
간의 데이터 전송 속도를 조절하여 네트워크의 혼잡을 방지하고 안정적인 통신을 유지하는 메커니즘이다.
receiver buffer
에 자리가 2개밖에 남지 않았는데sender
가packet
을 100개를 우루루 쏟아 부어도 어차피 2개밖에 들어가지 않는다.
flow control
은 receiver buffer
의 남은 자리에 맞춰 sender
가 적절한 개수로 packet
을 전송하는 것이다.
그럼 recevier
는 sender
에게 어떻게 빈공간의 용량을 알려줄까 ?
receiver
가 sender
한테 보내는 packet
의 header
부분에 received buffer
라는 공간에 얼마나 남았는지를 보내준다.
Q. 그냥 우다다다닥 쏟아붓고 리시버가 잘 받든 말든 우다닥 쏟아붇고 계속 재전송 하면 안되나요 ?
## A. 안됩니다
만약 리시버가 받지 못하는 상황에서도 flow control
없이 packet
을 계속해서 보내면 네트워크에서 혼잡이 발생하게 된다.
혼잡이 발생하면 부정적인 영향이 발생 할 수 있다.
recevier
는 데이터를 계속 받지 못하여 packet
이 손실되고 불필요한 재전송이 발생하게 된다.sender
의 buffer
가 가득 차면 큐잉 딜레이가 발생 할 수 있다. 이는 패킷이 대기열에 추가되어 처리되기 까지의 지연이 발생한다.flow control
은 recevier
의 상태에 따라 보내는 속도를 줄여, 데이터의 전송 속도를 줄일지언정 큰 그림으로 본다면 네트워크의 혼잡을 감소시켜 결국에는 가장 최적의 시간으로 전체 데이터를 전송시킨다.
위에서는 예시로 flow control
을 recevier
의 buffer
크기를 가지고만 이야기 하였지만
이 말고도 다양한 경우에 따라 flow control
을 한다.
어떤 경우에 recevier buffer
가 가득 찰 수 있을까 ?
등등 .. 다양한 경우가 존재한다.
만약 A 는 sender
, B 는 receiver
라고 해보자
A 가 B 에게 우다다닥 패킷을 쏟아 부었는데 B는 버퍼에 자리가 없어서 모든 데이터를 받지 못한다.
(버퍼에 자리가 없는 이유는 애플리케이션에서 버퍼에 있는 패킷을 읽는 속도가 느려서라고 가정하자)
B는 데이터를 받지 못했더라도 A한테 받은 데이터에 대해 ACK 를 보내야 하기에 ACK 를 보낼 것이다.
B : ACK %% (마지막에 받은거) , 남은 공간 : 0 / 10
A : 남은 공간이 없다니까 기다려야겠당
그럼 A 는 B의 자리가 날 때 까지 기다린다. (flow control
)
그럼 언제까지 기다릴까 ?
A는 가만히 기다리지 않는다.
A는 B에 자리가 언제 남았는지를 알아야 하고, 자리가 날 때 마다 빠르게 패킷을 재전송 해야 하기 때문에
아주 작은 용량의 데이터를 일정 기간동안 계속하여 보낸다.
계속 보내야 B 에게서 ACK
가 날라올 것이고 그 ACK
안에 B 의 남은 공간에 대한 정보가 있으니까 말이다.
Q . 그런데 그렇게 sender가 확인을 위해 보낸 작은 데이터들은 recevier 측에서 애플리케이션 레이어에서 어떻게 처리해 ? 불필요한 더미 데이터잖아
A . Flow control에서 송신자가 주기적으로 작은 데이터를 전송하는 것은 주로 TCP에서 사용되는 혼잡 제어 및 흐름 제어 기술의 한 부분입니다. 이 작은 데이터들은 실제로 불필요한 더미 데이터가 아니라, 수신자의 상태를 감지하고 효과적인 통신을 유지하기 위한 목적으로 사용됩니다.
이러한 작은 데이터를 흔히 "
TCP Keep-Alive
"나 "Window Probe
"라고 합니다. 여기에는 몇 가지 관련된 개념이 있습니다:
TCP Keep-Alive
:TCP Keep-Alive는 송신자와 수신자 간의 연결이 유효한지 확인하기 위해 사용됩니다. 일정 시간 동안 데이터 전송이 없을 때 송신자가 수신자에게 Keep-Alive 메시지를 보내어 응답을 확인합니다.
Window Probe
:혼잡 제어와 흐름 제어의 일부로 사용되는 윈도우 프로브는 수신자의 윈도우 크기 정보를 확인하기 위해 송신자가 주기적으로 작은 데이터를 보내는 것입니다.
이러한 작은 데이터는 애플리케이션 레이어에 직접적으로 영향을 미치지 않습니다. 그 대신, TCP 스택에서 처리됩니다. 송신자가 이러한 작은 데이터를 보내면 수신자는 그에 대한 ACK를 보내어 수신자의 상태 및 윈도우 크기 정보를 전달합니다. 이로써 송신자는 효과적으로 데이터를 전송할 수 있는 양을 조절하고, 혼잡을 피하며 안정적인 통신을 유지할 수 있습니다.
요약하면, 이러한 더미 데이터 또는 작은 양의 데이터는 주로 TCP 레이어에서 처리되며, 애플리케이션 레이어로는 전달되지 않습니다. 이 작은 양의 데이터는 주로 흐름 제어와 관련이 있으며, TCP 스택 내에서 처리되어 수신자의 윈도우 크기를 확인하거나 연결의 활성 상태를 유지하는 데 사용됩니다.
Connection management
TCP 통신이 이어지기 위해서는 우선 클라이언트와 서버측의 소켓이 서로 연결 되어 있어야 한다.
TCP간 연결이 일어나야 하는데 이를 TCP 3-way handshake
라고 한다.
왜 3-way
? 3번 왔다갔다 한다.
클라이언트 측에서 서버측에게 연결을 시작하자며 신호를 보낸다. (신호는 패킷을 보내면서 시작하는데 데이터는 비어있고 헤더 측에 SYN : 1
, 처음 보내고자 하는 패킷의 seq number
를 보낸다.)
서버측은 클라이언트 측에게 연결을 시작해보자며 신호를 보낸다. (신호는 패킷을 보내면서 시작하는데 데이터는 비어있고 헤더 측에 SYN : 1
, 처음 보내고자 하는 패킷의 seq number
를 보낸다.)
그리고 클라이언트 측에서 받은 SYN
, Seq #
에 대해서 잘 받았다며 응답으로 ACK : 1 , ACK : x+1
을 보낸다.
SYN : 1 , 처음 보내고자 하는 패킷의 seq number
를 잘 받았다며 응답으로 ACK : 1 , ACK : y+1
을 보낸다.이후 서로 보내는 패킷의 헤더의 SYN
은 이젠 모두 0으로 설정된다.
그리고 TCP 3way handshake 가 일어난 이후에는 (서로 연결이 됐으면) 각자가 보내려고 하는 패킷들의 sequence number 를 알고 있기 때문에 양측 모두 send , recevier buffer 를 생성하고 패킷을 주고 받는다.
왜 3번이나 할까 ? 그냥 2번만 주고 받으면 되는거 아닌가 ? 클라이언트가 서버측에 SYN 받자마자 시작하면 안되나 ?
안됩니다
1. 양측의 도달 가능 여부를 알아야 한다. 2way 를 하게 되면 클라이언트는 서버측이 준비가 된 것을 확인해야 버퍼를 만들 수 있다.
2. TCP 는 point to point 연결이지만 3way 가 아니라 2way 를 하게 되면 한 클라이언트가 여러 서버와 연결이 될 수 있다.
3-way handshaking 할 때 마지막 신호인 클라이언트가 서버에게 보내는 ACK : 1 , ACK : y+1
에는 처음 보내고자 했던 패킷이 들어있을 수 있다. (seq = x
인 패킷)
클라이언트와 서버가 통신하는 그림을 살펴보면 2개의 신호 이후 클라이언트 측에서 HTTP 신호를 보내는데 이 신호는 3번째 신호 안엔 ACK 1 , ACK y+1
를 포함한 첫 번째 패킷이 들어있다.
서로 패킷을 모두 주고 받은 후에는 어떻게 closing
될까 ?
클라이언트 측에서 모든 데이터를 보냈다면 FIN
을 보낸다.
서버측은 클라이언트 측에서 보낸 FIN
에 대해서 ACK
를 보낸다.
서버측도 모든 데이터를 보냈다면 FIN
을 보낸다.
클라이언트 측도 서버측에서 보낸 FIN
에 대한 응답인 ACK
를 보낸다.
이미지에 있는 time waited
기간 동안에는 연결을 끊지 않고 각자의 buffer
들을 유지한채로 기다리고 있는다.
왜 ?
만약
time wait
이 존재하지 않아서 클라이언트는FIN
보내고ACK
만 받고 철수했다고 해보자
만약 클라이언트가 서버 측에게 보내는ACK
가 유실되었다고 해보자
그럼 서버는 ACK 못받았으니까 기다리다가 타임아웃이 발생하고 FIN 을 계속 보낼 것이다.
근데 클라이언트는 철수 했으니 계속 FIN 만 애타게 울부짖으며 철수를 못한다.
time wait
는 확실하게ACK
를 받기 위해 준비하는 시간이다.
이건 복습하면서 보자
혼잡 제어 (congestion control
)는 네트워크에서 데이터의 전송 속도를 효과적으로 조절하여 혼잡 현상을 방지하고 네트워크 성능을 최적화 하는 메커니즘이다.
만약 네트워크가 20개의 패킷을 처리 할 수 있고 , 리시버가 10개의 패킷을 처리 할 수 있다면
sender 는 10개의 패킷을 보내야 할 것이다.
이는 recevier 의 buffer 의 남은 양을 .리시버에게 받은 ACK 를 통해 알 수 있다.
그럼 만약 네트워크는 5개만의 패킷을 처리 할 수 있고 리시버가 10개의 패킷을 처리 할 수 있다면
sender 는 5개의 패킷을 보내야 할 것이다.
센더는 리시버의 상태만 살펴야 할게 아니라 네트워크의 상태도 신경써야 한다.
A 와 B는 point to point 로 연결되어 있지만 둘만의 네트워크를 가진게 아니다.
다른 서버, 클라이언트들도 사용하는 공용 네트워크에서 A와 B가 연결되어 있을 뿐이다.
모든 연결된 쌍들은 서로가 보내는 양이 제일 많기를 기대할 것이다.
아 나는 빨리 보내고 싶다고 ~~
그런데 만약 그렇게 보내는 양을 최대화 할 경우 네트워크의 혼잡도는 올라가게 될 것이다.
고속도로 생각해봐 차들이 많으면 차가 막히잖아
네트워크가 악화되면 재전송이 일어나면서 더 혼잡해지고 더 막히고 더 재전송하고 더 혼잡해지고 ..
악의 순환고리인거다.
그러니 각 서버, 클라이언트 쌍들은 서로 보내는 양을 최대화 하면서도 네트워크의 혼잡도를 높이지 않을 만큼의 적절한 양을 신경 써야 한다.
근데 UDP 는 신경 안쓰고 우다다닥 쏟아붓는 무법자임
TCP
는 혼잡도가 올라가면 보내는 양을 줄여야 할 것이다.
그럼 TCP
는 네트워크 환경을 어떻게 인식할건데 ?
network-assited congestion control
: 네트워크가 직접적으로 TCP
에게 네트워크의 상황을 알려주는 방법 그런데 구현은 안되있음 , 라우터들은 데이터 보내기에도 바빠 죽겠음
End-end congestion control
: 실제 인터넷에서 구현되어 있는 방식으로 양 엣지에 위치한 서버와 클라이언트가 내부 상황을 유추해서 알아서 한다.패킷을 보내고 받는 ACK 의 정보들을 통해 유추한다. 자세한 내용은 다음 강의에서 고고씽
TCP
는 sender
와 recevier
의 상태에 따라 네트워크를 보내는 양을 조절한다.sender
가 10개씩 보내는 상황에서 recevier
의 buffer
가 5개만 받을 수 있다면 이젠 5
개씩만 보낸다.recevier
가 보내는 ACK
안에는 패킷을 받을 수 있는 buffer 의 양
의 정보또한 포함 되어 있음3-way-handshake
가 일어난다.SYN : 1 , 보내려고 하는 첫 번째 패킷의 seq number
를 보낸다.SYN , seq #
를 받았다며 SYN ACK , ACK 1
을 보낸다.SYN : 1 , 보내려고 하는 첫 번쨰 패킷의 seq number
를 보낸다.SYN , seq #
를 받았다며 SYN ACK , ACK1
을 보낸다.3way handshake
가 끝나면 서버 , 클라이언트 모두 buffer
를 생성하고 통신 시작 ! FIN , ACK
를 주고 받는다.FIN , ACK
를 주고 받으면 마지막 FIN
으로부터 time waited
를 한다.FIN
이 끝났음을 상대방이 오케이 하고 보낸 ACK
를 받을 때 까지 기다려야 한다.ACK
신호가 오면 각자 준비한 buffer
를 없애고 통신 종료 !