15-7 Flow Control
=> 원래대로라면 TCP는 Stop& Wait의 방식으로 구현되는데, 이는 상당히 비효율적이다. 또, 패킷을 여러 번 보낼 수도 있지만, 이는 패킷의 용량이 아깝다.
: 그렇기 때문에 한꺼번에 데이터를 많이 보내려고 한다. 보내는 TCP는 상대방이 소비하는 속도에 맞춰 패킷 한번에 rwnd만큼의 데이터를 한꺼번에 전송하게 된다.
<Sliding window>
: 이를 위해서 TCP는 Sliding window라는 기법을 도입하게 된다. 창의 크기를 가변적으로 조절하여 필요에 따라서 창의 크기를 크게(줄일수도 있지만 다루지 않음) 해서 여러 패킷을 논리적인 하나의 패킷으로 묶어 전송하고자 한다.
- Window의 크기 결정
=> window size는 rwnd와 cwnd 중 더 작은 값을 고른다.
-> Rwnd: 수신자가 받을 수 있는 window 크기
-> Cwnd: 송신자가 보낼 수 있는 패킷 크기의 한계
<Sending buffer의 window>
1) Closing: sender가 ack 번호를 보고 상대방이 어디까지 받았는지를 확인하고, 상대방이 다 받았다면 더 이상 keep 할 필요가 없으니 반납하고 빈공간을 만든다.
2( Opening : 데이터가 reciever에서 소비되어 보낼 수 있는 양이 늘어나면 right wall이 오른쪽으로 더 이동한다.
(Shrinking은 다루지 않음)
<Receiving buffer의 window>
1) Closing: sending buffer로부터 데이터를 받은 만큼 left wall은 close된다.
2) Opening: 데이터가 receiver에서 소비된만큼 right wall이 오른쪽으로 이동하여 window가 열린다.
- Flow control Feedback
: 상대 destination의 receiving 버퍼가 소비되는 속도를 고려하여 그에 맞춰 TCP가 보내는 패킷의 양을 조절하는 것이다.
1) TCP가 Application으로부터 데이터를 가져와 채운다.
2) window size만큼 데이터를 전송한다
3) receiving buffer로 전송받은 데이터가 소비된다
=> consume된 만큼 빈공간이 생긴다
4) window size를 feedback한다
5) 다시 write를 호출하면 Transport layer가 버퍼에 데이터를 채움
6) 소비후에 비었다고 피드백 받은 만큼 데이터를 다시 보내준다.
EX) 이미지 파일 같이 큰 파일을 보내려고 할 때
=> 이미지 용량이 buffer보다 크면 write()에서 block된다. 따라서 상대방이 정보를 가져가야 block이 풀리고 TCP가 또 새로운 데이터를 갖다놓는다
: Receiving buffer가 소비를 하는 속도만큼만 Sending buffer에 갖다놓고, receiving buffer로 데이터를 전송한다. ->이를 flow control이라고 한다.
+) 버퍼로 데이터를 갖다놓고/ 보내는 것은 서로 독립된 과정으로 , sync가 안 맞을 수도 있다.
버퍼가 꽉차면 block하고, 채워진 데이터는 알아서 잘 여러 패킷으로 쪼개져서 보내진다.
<EXAMPLE of FLOW CONTROL>
<클라이언트-서버 연결 요청>
1) 클라이언트가 서버로 연결 요청 패킷을 보냄
2) 서버가 SYN+ACK 패킷을 보내준다. 해당 패킷에는 rwnd=800이라는 값이 적혀있다.
->ACK number값은 101이다.
3) 클라이언트가 해당 SYN 패킷에 대한 ack패킷을 보내준다.
<데이터 전송>
4) 이제 데이터를 101번부터 200byte보낸다.
: 이때 Sending buffer는 아직 변화가 없다. Receiving buffer는 200byte를 보냈으니 200만큼 줄어든다. (#301~#901)
5) 서버가 이제 600byte가 남았으니 ack 패킷에 rwnd값으로 600을 보내준다.
=> client가 101~301까지 보낸 데이터에 대한 ack을 받았으니 해당 window는 301번 까지는 window를 close한다. (#301~#901)
6) 이제 client가 다시 301번부터 300byte를 보낸다. 이때 서버가 300byte를 받고, 100byte를 소비했으니 앞 wall은 300byte만큼 close하고, right wall은 100byte만큼 열어준다. (#601~#1001)
7) 이제 서버가 다시 300byte에 대한 ack을 보내준다. rwnd값은 400을 보내준다. 이제 sending buffer는 300byte를 제거하고, 뒤에 100byte만큼 열어준다. (#601~#1001)
8) 마지막으로 서버가 스스로 200byte를 소비하여 receiving buffer의 window가 #601~#1201까지 열렸다. 이제 rwnd값이 늘어났다고 ack 패킷을 sending buffer로 rwnd=600만큼 보내준다.
-> 이제 sending buffer는 #601~#1201만큼 전송받고 해당 그림의 프로세스는 종료가 된다.
- 실제 Flow control에서는?
: 실제로는 rwnd값은 단위가 훨씬 크다. MSS라는 단위만큼 주고받는데, 1MSS의 크기는 500byte이다.
=> 따라서 rwnd=n x MSS로 표현이 된다.
EX) rwnd값이 5000byte라고 가정해보자. 그리고 sender의 sliding window는 #6001~#11000 까지라고 가정한다.
: 5000byte를 한꺼번에 보낼 수도 있지만 패킷의 size는 maximum 500byte로 정해져 있다. 따라서 패킷 10개를 동시에 보내야 한다.
=> 첫 패킷 #6001번부터 시작해 패킷을 10개 다 보내면 첫 패킷에 대한 ACK이 올 때 까지는 stop하고 더 이상 보내지 않는다.
=> Sender의 window size는 첫번째 보낸 패킷에 대한 ACK이 도착한 순간 다시 세팅한다.
- 첫번째 패킷에 대한 ACK num이 6501이 왔는데, 이에 대한 rwnd가 5000이 왔다면 이미 받았지만 또 그사이에 소비가 되어 500byte만큼 자리가 생긴것이므로 (아직 나머지 9개 패킷은 못받은 상태), sending buffer의 right wall을 500byte만큼 open하고, 500byte 짜리 패킷을 하나 더 보내고 stop하게 된다. (Sending buffer window: #6501~#11500)
=> 이렇게 receiving buffer가 소비하는 속도 만큼만 sending buffer에 갖다놓게 된다.
'Computer Science > Computer Network' 카테고리의 다른 글
Window Size란? (1) | 2020.10.26 |
---|---|
Time-wait은 왜 발생하는가? (0) | 2020.10.25 |