Проблема с задержкой пакетов на TCP / IP Windows 7 loopback адаптере (или ошибка в программном обеспечении?) - PullRequest
2 голосов
/ 16 марта 2011

У нас есть клиентское и серверное приложение, которое в настоящее время тестируется на одной и той же Windows 7 64-битной машине. Они оба написаны на C # и используют P / Invoke для вызова библиотек Winsock2.

Приложение отлично работает без ошибок. И задержка для каждого «прыжка» по tcp / ip составляет в среднем около 350 микросекунд.

Однако иногда случаются очень длительные задержки от 40 до 50 мсек до получения пакетов, а затем внезапно все они приходят.

Попытки диагностировать до сих пор:

  1. Во время этих задержек получения данных сервер продолжает регистрировать, что он отправляет пакеты. Он настроен на отправку тестовых пакетов каждые 1 мс, что он будет делать в течение 15 или 20, а иногда и до 50 мс, прежде чем клиент получит любой из них.

  2. tcpdump использовался для перехвата пакетов на адаптере обратной связи и показывает, что в течение этого периода задержки существует трафик с порта сервера (6488) на порт клиента (61743), как обычно.

  3. Клиент вызывает вызов winsock2 select () в цикле, поэтому регистрация через счетчик до вызова select () показывает, что он имеет правильный дескриптор файла. И, конечно, это прекрасно работает до и после задержки.

  4. Дальнейшее ведение журнала сразу после вызова select () показывает, что fd отсутствует - это означает, что чтение в сокете будет блокироваться. Однако в течение периодов передачи без каких-либо задержек протоколирование показывает, что оно работает должным образом, поэтому select () возвращает fd сокета для неблокирующего чтения.

Короче говоря, адаптер обратной петли, кажется, долго удерживает эти пакеты где-то еще до окончательной доставки их получающей стороне.

Есть еще идеи или решение?

Некоторые считают, что часто утверждают, что перекрывающийся ввод-вывод работает лучше в Windows, но для масштабируемости это имеет значение, только если вам нужно прослушать более 64 сокетов.

Может ли быть так, что переключение на перекрытие поможет? Мы хотим избежать, так как это увеличит сроки проекта и бюджет. Это должно работать с select () просто отлично.

Кроме того, может ли процесс или поток в Windows, который обрабатывает обратную петлю, переключаться на контекст или что-то в этом роде, и, если да, есть ли способ настроить его, чтобы избежать этих задержек?

Редактировать: правильный ответ состоял в том, чтобы убедиться, что алгоритм Nagle был отключен. Мы думали, что он был отключен, но именно здесь была обнаружена ошибка - в нашей собственной реализации SetSocketOption () мы использовали GetSocketOption () для проверки. Таким образом, оказывается, что вы должны установить NoDelay до подключения или привязки сокета, иначе он молча не даст никакого эффекта.

Большое спасибо Fun Mun Pieng за правильный ответ !!!

1 Ответ

3 голосов
/ 16 марта 2011

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

socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...