Странная проблема send () (с журналом Wireshark) - PullRequest
2 голосов
/ 22 апреля 2010

У меня был еще один вопрос по этой проблеме, но я не задал его должным образом, поэтому я снова здесь!

Я отправляю файл, отправляя его частями.Сейчас я играю с разными числами для размера этого чанка, чтобы увидеть, какой размер является наиболее эффективным.

При тестировании на локальном хосте любой размер чанка, кажется, работает нормально.Но когда я тестировал его по сети, кажется, что максимальный размер порции составляет 8191 байт.Если я попробую что-нибудь выше, передача станет чрезвычайно, мучительно, медленной.

Чтобы показать, что происходит, вот первые 100 строк журналов Wireshark, когда я использую чанк размером 8191 байт и когда я используюразмер фрагмента 8192 байта: (отправитель 192.168.0.102, а получатель 192.168.0.100)

8191: http://pastebin.com/E7jFFY4p

8192: http://pastebin.com/9P2rYa1p

Обратите внимание, что в журнале 8192 в строке 33 получателю требуется много времени для подтверждения данных.Это происходит снова в строке 103 и строке 132. Я полагаю, что эта задержка является корнем проблемы.

Обратите внимание, что я не изменил ни параметр SO_SNDBUF, ни параметр TCP_NODELAY.

Так что мой вопрос Почему я получаю ACK с задержкой при отправке файлов кусками по 8192 байта, когда все работает нормально при использовании кусков по 8191 байта?

Ответы [ 2 ]

1 голос
/ 24 апреля 2010

Я понял это! Сначала я сам, а потом еще немного покопался и обнаружил: http://support.microsoft.com/kb/823764

На самом деле происходило то, что, поскольку буфер отправки, выделенный Winsock, по умолчанию (на моей машине) ровно 8192 байта, когда я помещаю это количество байтов в буфер (фактически полностью заполняя его), следующая отправка ( ) даст WSAEWOULDBLOCK. Тогда я получу следующий FD_WRITE только после подтверждения байтов.

Но в то же время принимающая машина не отправляла ACK из-за отложенного алгоритма ACK. Это поставило передачу в тупик на 200 мс, после чего принимающая машина, наконец, ACKs передает данные, что затем позволяет отправляющей функции получить FD_WRITE.

Конечно, всего этого не происходит, когда я использовал 8191 байт, потому что я не заполнил весь буфер, и, таким образом, следующий send () не заблокировал. Это означало, что Winsock всегда будет продолжать посылать данные, чтобы задержанный алгоритм ACK никогда не включался на принимающей стороне (кроме последнего пакета, если это пакет с нечетным номером).

Надеюсь, это поможет кому-то еще с той же проблемой, с которой я столкнулся.

0 голосов
/ 23 апреля 2010

Проверьте настройку «Flow Control» на сетевых картах и ​​коммутаторах. Если он включен, это может быть причиной вашей проблемы.

А для правильного вскрытия вам нужно будет запустить wireshark на обоих концах передачи.

...