Windows는 작은 패킷들의 효율적 처리를 위해 200ms까지 ACK를 Waiting 한다.

|

참고 사이트 : 30바이트 전송하는데 1분이나 걸릴까?
참고 사이트 : 디자인 문제 - Winsock을 사용하는 TCP를 통해 작은 데이터 세그먼트 보내기 (번역)

아마도 현재 나와있는 모든 Windows Edition에서 동일할 것으로 생각된다.
요청과 응답이 1:1로 매치되는 Client - Server 구조에서는 이 현상이 영향을 미치지 않는다.
요청과 응답이 1:n으로 매치되는 Client - Server 구조에서도 지연시간이 200ms이상 지연되면 문제가 생길 수 있는 구조에서는 이 현상이 영향을 미친다.

아래의 Client - Server 구조는 Windows Client VS Linux Server에서 도출해 낸 자료이다.

Ethereal에서 Packet 상태를 찍어보면 다음과 같다. (이 자료는 정확히 둘다 TCP_NODELAY 옵션이 없는 상태에서 찍은 것이 아니다. 하지만 해당 경우와 비슷한 타임 프레임이 발생하기에 예로 삼았다.)

사용자 삽입 이미지

ACK가 Waiting 되는 상황이다.

  1. 611번 프레임에서 Client는 Server에게 특정 요청을 보낸다.
  2. 612번 프레임에서 Server는 Client에게 여러 데이터를 보내지만, 특별히 611번 프레임의 결과에 대한 응답은 아니다. 이 응답은 미묘한 차이로 다음 순서로 대기된다. (612번 프레임에서 611번 프레임의 결과가 같이 올 수 있으면 이 현상이 해결된다. 가끔 그렇게 결과가 오기도 하기 때문에 매번 이런 문제가 발생하지는 않는다.)
  3. 612번 프레임과 613번 프레임 사이에서 Client는 Server로 보낼 데이터가 없기 때문에 200ms동안 Waiting 하고, Server는 Client로 보낼 데이터 (611번 프레임의 요청에 대한 결과) 가 있지만, Client로부터 ACK를 받지 못했기 때문에 Waiting 하고 있다.
  4. 613번 프레임에서 Client는 새로운 요청이 생겼다.
  5. 614번 프레임에서 Server는 613번 프레임의 요청에 대한 응답과 함께 611번 프레임에 대한 응답을 보낸다. 611번 프레임에 대한 응답은 보다시피 0.13sec 정도의 지연이 발생하였다.

이 지연을 해소하려면 1) Client에서 Delayed ACK 를 비활성화 해주거나, 2) 서버쪽에서  TCP_NODELAY 옵션을 활성화(Nagle Algorithm을 비활성화)해야 한다.

Server쪽에서 TCP_NODELAY 옵션을 활성화하면 다음과 같은 Packet 모양이 발생한다.

사용자 삽입 이미지

ACK를 Waiting 하지 않는 상황이다.

  1. 549번 프레임에서 554번 프레임까지는 위와 같은 동작을 수행한다.
  2. 555번 프레임에서 Server는 보낼 데이터가 하나 더 생겼다. 이 데이터는 TCP_NODELAY가 활성화되지 않았다면 556번 프레임의 ACK를 받은 후에 보내졌을 것이고, 이전의 경우와 마찬가지로 0.1xsec 정도의 지연이 발생했을 것이다.
  3. 556번 프레임에서 클라이언트는 즉시 ACK를 보낸다. 이 ACK는 554번 프레임에 대한 ACK이며, ACK를 보내지 않은 프레임(554번 프레임)의 다음 프레임(555번 프레임)이 도착했기 때문에 서둘러 보낸 것이다.
  4. 557번 프레임은 555번 프레임의 요청에 대한 ACK이며, 역시 0.14sec정도의 지연 후에 보내졌으며, 데이터를 담고 있다.

Windows Client에서 Delayed ACK를 비활성화하는 방법으로 해결하는 방법은 테스트를 해 보지 못했다.

2008/03/07 - [프로그래밍/Utility, ETC] - Windows에서 Delayed ACK를 사용하지 않도록 세팅하기


And