Задержки отправки и повторной передачи сокета TCP - PullRequest
0 голосов
/ 26 октября 2009

У меня есть приложение .NET 3.5 C #, которое отправляет 2000-6000 байтовых пакетов на машину linux с sles 10. Машины находятся в одной подсети.

Примерно в 90% случаев все работает нормально. Машина linux обрабатывает мой запрос и отвечает в течение 5-15 мс. Но примерно в 10% случаев задержка составляет около 200-800 мс.

Глядя на журналы на машине Linux, кажется, задержка на моем конце. То есть, если мой вызов socket.Send (...) возвращается в 1: 15: 00.000, а я получаю ответ в 1: 15: 00.210, в журнале на машине linux говорится, что он получил запрос в 1:15 : 00.200, а затем обработали его за 10 мс. (Я использую System.Diagnostics.Stopwatch для синхронизации на моей машине.)

Для отладки я перехватил трафик с помощью wireshark. Здесь движение. Между № 8 и 9 происходит задержка в 600 мс. (137.34.210.108 - моя машина, а 137.34.210.95 - машина linux).

"1","11:56:27.380318","137.34.210.95","137.34.210.108","TCP","20700 > 17479 [PSH, ACK] Seq=1 Ack=1 Win=32767 Len=76"
"2","11:56:27.380393","HewlettP_29:37:0f","Broadcast","ARP","Who has 137.34.210.95?  Tell 137.34.210.108"
"3","11:56:27.380558","HewlettP_29:39:93","HewlettP_29:37:0f","ARP","137.34.210.95 is at 00:1b:78:29:39:93"
"4","11:56:27.380564","137.34.210.108","137.34.210.95","TCP","17479 > 20700 [ACK] Seq=1 Ack=77 Win=65459 [TCP CHECKSUM INCORRECT] Len=0"
"5","12:04:48.096892","HewlettP_29:37:0f","Broadcast","ARP","Who has 137.34.210.95?  Tell 137.34.210.108"
"6","12:04:48.097216","HewlettP_29:39:93","HewlettP_29:37:0f","ARP","137.34.210.95 is at 00:1b:78:29:39:93"
"7","12:04:48.097229","137.34.210.108","137.34.210.95","TCP","17480 > 20600 [PSH, ACK] Seq=1 Ack=1 Win=64198 [TCP CHECKSUM INCORRECT] Len=458"
"8","12:04:48.097457","137.34.210.95","137.34.210.108","TCP","20600 > 17480 [ACK] Seq=1 Ack=4294964377 Win=32767 Len=0 SLE=1 SRE=459"
"9","12:04:49.700966","137.34.210.108","137.34.210.95","TCP","17479 > 20700 [ACK] Seq=1 Ack=77 Win=65459 [TCP CHECKSUM INCORRECT] Len=1460"
"10","12:04:49.701190","137.34.210.108","137.34.210.95","TCP","[TCP Retransmission] 17480 > 20600 [ACK] Seq=4294964377 Ack=1 Win=64198 [TCP CHECKSUM INCORRECT] Len=1460"
"11","12:04:49.703970","137.34.210.95","137.34.210.108","TCP","20600 > 17480 [ACK] Seq=1 Ack=4294965837 Win=32767 Len=0 SLE=1 SRE=459"
"12","12:04:49.703993","137.34.210.108","137.34.210.95","TCP","[TCP Retransmission] 17480 > 20600 [ACK] Seq=4294965837 Ack=1 Win=64198 [TCP CHECKSUM INCORRECT] Len=1460"
"13","12:04:49.704002","137.34.210.108","137.34.210.95","TCP","[TCP Retransmission] 17480 > 20600 [PSH, ACK] Seq=1 Ack=1 Win=64198 [TCP CHECKSUM INCORRECT] Len=458"
"14","12:04:49.704211","137.34.210.95","137.34.210.108","TCP","20600 > 17480 [ACK] Seq=1 Ack=459 Win=32767 Len=0"
"15","12:04:49.704215","137.34.210.95","137.34.210.108","TCP","[TCP Dup ACK 14#1] 20600 > 17480 [ACK] Seq=1 Ack=459 Win=32767 Len=0 SLE=1 SRE=459"
"16","12:04:49.705425","137.34.210.95","137.34.210.108","TCP","20700 > 17479 [PSH, ACK] Seq=77 Ack=1461 Win=32767 Len=44"

Может ли кто-нибудь помочь мне интерпретировать это? Я вижу, что происходит повторная передача. Но я не уверен почему. Коммутатор не показывает пропущенных пакетов. И даже если пакеты теряются, почему для повторной передачи потребуется 600 мс?

Я думал, что это (http://support.microsoft.com/kb/328890) может иметь какое-то отношение к задержкам 200 мс, но я пытался изменить TcpAckFrequency, и это не помогло.

Спасибо, Mike

Ответы [ 3 ]

3 голосов
/ 27 октября 2009

Давайте начнем с сокращения некоторых выводов Wireshark. Мы можем выбросить ARP в пакетах 2, 3, 5 и 6. Глядя на остальное, у вас есть два набора трафика. Пакеты 8 и 9 - это два разных соединения, поэтому их нельзя сравнивать. 7, 8 и 10, однако, являются частью одного соединения, поэтому давайте рассмотрим их.

Пакет 7 - это 458 байт данных, отправляемых на блок Linux с порядковым номером TCP 1. Однако ACK, возвращаемый блоком Linux, равен 4294964377. Это означает, что Wireshark показывает относительные значения TCP и что блок Linux не отправляет ACK для пакета 7, но для более раннего пакета. Затем ваш компьютер ожидает подтверждения ACK и, когда он не получает его, повторно передает необходимые данные. В этом случае 458 байтов из пакета 7 вместе с предыдущими 1002 байтами. Вот почему порядковый номер из пакета 10 совпадает с ACK из пакета 8.

К сожалению, это не говорит вам, почему данные отбрасываются. Пакет 8 показывает окно Linux, указывающее, что у него все еще есть 32 КБ входного буфера, доступного для этого соединения («Win = 32767»).

0 голосов
/ 27 октября 2009

Я не помню, есть ли в Windows, но в UNIX вы бы включили TCP_NODELAY.

Это отключает алгоритм Nagle TCP, который заставляет систему немного подождать, если в буфер передачи будет добавлено больше данных.

int nodelay = 1;
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));
0 голосов
/ 26 октября 2009

Здесь отображаются только пакеты TCP на компьютере с Linux, но я бы порекомендовал посмотреть статистику ip с помощью команды netstat -s. Одной из причин повторных передач могут быть переполнения буфера сокетов, которые будут показаны с помощью этой команды.

...