TCP Sliding Window

2 분 소요

TCP는 UDP와 달리 연결지향(connection-oriented) 프로토콜로 종단간 신뢰성 있는 데이터 전송을 보장한다. 여기서 연결지향이라는 것은 cicruit network처럼 물리적인 회선을 만드는 것이 아니라, 논리적인 연결을 유지한다는 것이다.

TCP는 TCP 세그먼트를 신뢰성 있게 전달하기 위해 비연결 프로토콜인 IP위에 아래의 3가지 기능을 추가했다.

  1. TCP 체크섬
  2. 시퀀스 번호
  3. 흐름제어/혼잡제어

오늘은 이중 흐름제어에서 사용하는 Sliding Window에 대해서 다룰 것이다.

TCP로 통신하는 두 프로세스는 Stop and Waiting ARQ보다 효율적인 데이터 전송을 위해 각각의 윈도우(Window)를 유지한다. 송신측은 송신 윈도우를 유지해 송신 윈도우 크기만큼 한 번에 데이터를 보낼 수 있다. 마찬가지로 수신측은 수신 윈도우를 유지하며 이 크기만큼 데이터를 한 번에 받을 수 있다. 양측 윈도우 크기는 TCP 헤더의 Window Size 필드에 의해 설정된다.

TCP 수신 윈도우

예를 들어 그림 1에서 A는 TCP 수신 윈도우를 나타낸다. 이때 윈도우의 크기는 4이며 최대 4Byte까지 ACK 송신 없이 받을 수 있다. A에서 시퀸스 번호 1, 2는 수신해서 이미 ACK를 보낸 바이트이다. 3 ~ 6번은 아직 수신하지 않았지만 수신할 준비가 되어 있는 바이트이며 7번부터는 수신준비가 되지 않은 바이트이다. 수신측은 윈도우 범위를 넘어서는 바이트에 대해서는 무시한다.

만약 들어오는 세그먼트에서 처음 수신되는 바이트가 윈도우의 왼쪽 끝(3번)과 다를 경우 순서대로 도착한 것이 아니기 때문에 재조립을 위해 버퍼에 보관한다. 수신한 바이트가 수신을 기대했던 번호(3번)이면 즉시 애플리케이션에 의해 처리되고 ACK를 전송하며 윈도우가 오른쪽으로 이동한다.

수신측 윈도우가그림 1의 A와 같을 때 송신측 윈도우는 그림 2의 A와 같다.

TCP 송신 윈도우

송신측은 윈도우 크기(4)만큼의 데이터를 ACK 수신 없이 보낼 수 있다. 이때 1~2번은 이미 ACK를 수신한 바이트고, 3~6번은 즉시 전송가능한 바이트, 7번부터는 아직 전송할 수 없는 바이트이다. 그림 2의 B는 3, 4번 바이트를 전송한 다음의 상태이다. 3, 4번은 전송했지만 ACK를 받지 않았고 5, 6번은 즉시 전송이 가능하다.

그림 1의 B는 3, 4가 수신된 뒤의 상태이다. 윈도우는 2개만큼 오른쪽으로 이동하고 ACK 번호 5를 전송해 다음 수신할 바이트가 5라는 것을 알려준다.

그림 2의 C는 ACK5를 수신한 뒤의 상태이다. 송신 윈도우 역시 2만큼 오른쪽으로 이동했다.

만약 3, 4를 전송했을 때 RTO(Retransmission Timeout)까지 ACK가 없을 경우 TCP는 3, 4번 바이트가 포함된 세그먼트가 유실되었다고 판단하고 재전송한다. RTO 타이머가 만료되었다는 것이 항상 세그먼트가 유실된것을 나타내지는 않는다. 세그먼트가 아직 수신측에 도달하지 않았을 수 도 있다. 혹은 수신측이 보낸 ACK가 유실되었을 수 도 있다.

만약 윈도우내 모든 데이터를 보냈지만 ACK가 오지 않는 경우 수신측은 윈도우를 이동시지 못하고 필요한 ACK를 기다려야 한다. 수신측은 재전송된 세그먼트를 받을 경우 윈도우가 이미 중복된 세그먼트의 순서번호를 포함하지 않기 때문에 수신측에서 중복된 세그먼트는 무시되고 ack만 전송된다.

이렇게 TCP 통신은 윈도우 사이즈를 통해 수신측에서 능동적으로 데이터 전송을 조절할 수 있다. 즉 수신측 버퍼보다 큰 데이터를 전송하지 못하게 해준다. 이때 TCP 헤더의 Window Size 필드를 통해 윈도우 사이즈를 제어한다.

TCP 윈도우 사이즈 조절

위 그림과 같이 수신측이 데이터를 충분히 빠르게 처리할 수 있다면 항상 최대치로 유지될 수 도 있다.

TCP 윈도우 사이즈 조절

반대로 수신측 상황에 따라 윈도우 사이즈가 점점 작아지게 조절될 수 도 있다. 혹은 0(zero window)가 되었다가 다시 커질 수 도 있다.

Window Size 필드의 크기가 2Byte이기 때문에 최대로 가질 수 있는 윈도우 사이즈는 2^16=65535이다. 이 크기는 요즘 인터넷에서 큰 데이터를 전송할 때 효율적이지 않을 수 있기 때문에 더 큰 윈도우 사이즈를 위해 TCP window scale option 를 이용할 수 있다.

TCP 윈도우 사이즈 조절

위 그림에서 Window Size 필드의 값은 63792이지만, Window Size Scaling Factor가 4임으로 윈도우 사이즈는 63792 * 4 = 255,168Byte이다.

이렇게 TCP 흐름 제어를 위한 Sliding Window에 대해서 알아보았다. 물론 제대로 흐름을 제어하려면 상황에 맞는 적절한 윈도우 사이즈를 구해야 한다. 보통은 min ( cwnd(수신측 혼잡 윈도우 크기), rwnd(수신측 윈도우 크기) ) 공식을 통해 구하게 된다. 혼잡제어는 다름에 다룰 것이다.


References

  • https://accedian.com/enterprises/blog/tcp-receive-window-everything-need-know/
  • Effective TCP/IP Programming, Jon C. Snader