2010-04-21 6 views
2

나는이 문제에 관해 다른 질문을했지만 올바르게 질문하지 않았으므로 여기서 다시 간다!이상한 send() 문제 (Wireshark 로그 사용)

파일을 청크로 보내 보내드립니다. 현재, 나는 그 크기의 다른 숫자를 가지고 놀고 있는데, 어떤 크기가 가장 효율적인 지 알기 위해서입니다.

로컬 호스트에서 테스트 할 때 모든 청크 크기가 정상적으로 작동하는 것 같습니다. 하지만 네트워크를 통해 테스트했을 때 최대 청크 크기는 8191 바이트 인 것 같습니다. 내가 더 높은 것을 시도하면, 전송은 매우 고통스럽고 느려집니다.

청크 크기를 8191 바이트로 사용할 때 Wireshark 로그의 처음 100 줄을 표시하고, 청크 크기를 8192 바이트로 사용할 때 다음과 같습니다 (발신자는 192.168.0.102이고 수신자는 192.168.0.102입니다. 인 192.168.0.100)

8191

:

8192 http://pastebin.com/E7jFFY4p 다음 8192 로그, 라인 (33)에, 수신기는 데이터를 ACK로 오랜 시간이 걸리는 http://pastebin.com/9P2rYa1p

통지. 이것은 103 행과 132 행에서 다시 발생합니다.이 지연이 문제의 근원이라고 생각합니다.

SO_SNDBUF 옵션이나 TCP_NODELAY 옵션을 수정하지 않았습니다.

그럼 내 질문은 왜 8191 바이트의 청크를 사용할 때 모든 것이 잘 작동 할 때 8192 바이트의 청크로 파일을 전송할 때 지연 ACK가 발생합니까?

+0

일부 코드를 표시 할 수 있습니까? 그것은 우리에게 무슨 일이 벌어지고 있는지에 대한 더 나은 단서를 줄 수 있습니다. 또한 코드가 양쪽에서 실행되고 있습니까? 또는 연결의 단지 1면? – Pretzel

+0

관련 섹션의 의사 코드를 추가했습니다. – Meta

답변

1

나는 그것을 알아 냈다! 먼저 자신에 의해, 그리고 더 많은 파기 후에, 나는 이것을 발견했습니다 :http://support.microsoft.com/kb/823764

실제적으로 Winsock에 의해 할당 된 송신 버퍼는 기본적으로 (내 컴퓨터에서) 정확히 8192 바이트이므로, 버퍼의 바이트 양 (효과적으로 완전히 채워짐), 다음 send()는 WSAEWOULDBLOCK을 제공합니다. 그런 다음 바이트가 ACK 되었다면 다음 FD_WRITE 만 수신합니다.

그러나 동시에 수신 기계는 지연 ACK 알고리즘 때문에 ACK를 보내지 않았습니다. 이것은 전송을 200ms 동안 교착 상태로 만든 다음, 수신 기계가 데이터를 ACK 한 다음 send 함수가 FD_WRITE를 수신하도록 허용합니다.

물론 전체 버퍼를 채우지 않았기 때문에 8191 바이트를 사용했기 때문에이 모든 현상이 발생하지 않습니다. 따라서 다음 send()가 차단되지 않았습니다. 이는 Winsock이 항상 지연된 ACK 알고리즘이 수신단에서 실행되지 않도록 데이터를 계속 전송한다는 것을 의미합니다 (홀수 번호의 패킷 인 경우 마지막 패킷 제외).

희망 사항은 내가 가진 동일한 문제를 가진 다른 사용자에게 도움이되기를 바랍니다.

0

NIC와 스위치의 "흐름 제어"설정을 확인하십시오. 켜져 있으면 문제의 원인 일 수 있습니다.

적절한 절개를 위해 전송 양 끝에 wireshark를 실행해야합니다.

+0

두 컴퓨터에서 Flow Control (흐름 제어)을 해제하고 다시 시도했습니다. 같은 결과.두 가지 모두 Wireshark를 사용하여 테스트를 다시 시도하고 로그를 게시합니다. – Meta