더북(TheBook)

이 문제를 피하기 위해, TCP는 연결 중에 ACK 없이도 여러 세그먼트를 한꺼번에 보낼 수 있다. 그렇다고 무제한으로 보내면 또 문제가 발생한다. 전송 계층의 데이터가 호스트에 도착하면 해당 포트에 바인딩한 프로세스가 데이터를 소비할 때까지 버퍼에 머무르게 된다. 호스트에 메모리가 아무리 많아도, 버퍼 자체는 고정된 크기로 만들어진다. 따라서 느린 CPU에서 돌아가는 복잡한 프로세스가 있으면 데이터를 소비하는 속도가 도착하는 속도를 따라가지 못하는 경우가 발생한다. 이렇게 되면 버퍼가 곧 가득 차서 추가로 수신되는 데이터는 버려진다. 그러면 송신 측 TCP 호스트는 이들 세그먼트에 대한 ACK를 받지 못해, 버려진 데이터를 빠른 속도로 다시 보내게 된다. 하지만 그래 봤자 수신 측 호스트는 여전히 느린 CPU에 복잡한 프로세스를 돌리느라 기껏 다시 받은 데이터를 또 버릴 것이고, 이 같은 악순환이 계속 이어지고 만다. 그 결과 엄청난 체증이 유발되어 막대한 인터넷 자원을 낭비하게 될 터이다.

이 같은 참사를 방지하고자, TCP는 흐름 제어(flow control) 기법을 사용한다. 빠른 송신 호스트가 느린 수신 호스트를 압도하지 못하게 제어하는 기법이다. 각 TCP 헤더엔 수신 윈도(receive window) 필드가 있어 패킷을 보낸 호스트의 수신 버퍼 여유량을 기재하게 되어 있다. 이는 곧 상대 호스트에게 말하길 “내가 이만큼의 데이터를 받을 수 있으니 그 이상 보내려면 ACK를 기다렸다가 보내라”는 의미가 된다. 그림 2-16에 흐름 제어를 통해 빠른 호스트 A가 느린 호스트 B와 패킷을 주고받는 절차를 묘사했다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.