TCP (Transmission Control Protocol) 는 이름에서 알 수 있듯이, 패킷 교환 방식 네트워크에서 패킷들이 안전하게 이동할 수 있도록 보장해주는 프로토콜이다. 크게 흐름제어, 혼잡제어 동작을 수행하는데, 이번 포스팅에선 그 중에서도 흐름제어 기법에 대해 살펴볼 것이다.
즉, 수신측이 너무 많은 패킷을 수신받지 않도록 하기 위함이다. 수신측에는 패킷을 수신받는 버퍼의 크기가 정해져있는데, 만약 송신측의 전송 속도가 너무 빨라 한 번에 수많은 패킷을 수신받아버린다면, 버퍼가 가득차 손실되는 패킷들이 발생할 것이다.
수신측의 처리 속도가 더 빠른 것은 문제가 되지 않지만, 위와 같은 상황처럼 송신측의 처리 속도가 더 빠를 경우 분명히 이를 제어할 수단이 필요하다. 따라서 TCP 에서는 흐름제어 기법을 사용한다.
흐름제어의 기본 개념은, 수신측이 송신측에게 자신의 상태를 계속하여 알리는 것이다. 즉, 데이터를 더 받을 준비가 되어있다는 피드백이 이루어졌을 때 송신측에서 패킷을 이어서 보내도록 하는 것이다.
우선, TCP/IP 계층에 의거하여 패킷이 전송되는 과정을 간략히 살펴보자.
Application Layer : 송신측 Application Layer 가 소켓에 데이터를 입력
Transport Layer : 데이터를 세그먼트로 감싸고 Network Layer 에 전달
수신측 노드로 세그먼트가 전송됨. 동시에 송신측의 Send Buffer 와 수신측의 Receive Buffer 각각에 데이터가 저장됨.
수신측 Application Layer 에서 준비가 되면, Receive Buffer 에 있는 데이터를 읽기 시작함
따라서, Receive Buffer 가 넘쳐나지 않도록 하는 것이 흐름 제어의 핵심!
→ 이를 위해 RWND(Receive Window, Receive Buffer 의 남은 공간) 을 송신측에 계속하여 피드백함
매번 전송한 패킷에 대한 확인 응답을 받아야만 그 다음 패킷을 전송하는 기법
수신측에서 설정한 윈도우 크기만큼 송신측에서 패킷 각각에 대한 확인 응답없이 세그먼트를 전송하게 하고, 데이터 흐름을 동적으로 조절하는 기법
전송은 되었으나, ACK 을 받지 못한 Byte 크기를 파악하기 위해 사용
LastByteSent - LastByteAcked ≤ ReceiveWindowAvertised
→ 마지막에 보낸 바이트 수 - 마지막에 확인된 바이트 수 ≤ 버퍼 남은 공간
(현재 이도저도 못하고 있는 패킷 수 ≤ 슬라이딩 윈도우 크기)
윈도우 크기만큼 패킷을 모두 전송하고, 그 패킷들의 전달이 확인되는대로 해당 윈도우를 옆으로 슬라이딩하면서 그 다음 패킷을 전송하는 방식으로 동작한다.
TCP/IP 를 사용하는 모든 호스트들은 송신 그리고 수신을 위한 2개의 Window 를 가지고 있다. 호스트들은 실제 데이터를 보내기 전에 3-Way Handshake 를 통해 연결 설정을 해줄 때 수신 호스트의 Receive Window 크기에 자신의 Send Window 크기를 맞춰 설정한다.
세부 동작을 살펴보면 다음과 같다.