Вопросы проектирования - Отправка сегментов небольших данных по протоколу TCP с Winsock

Переводы статьи Переводы статьи
Код статьи: 214397
Развернуть все | Свернуть все

В этой статье

Аннотация

При необходимости отправки пакетов небольших данных по протоколу TCP, проект приложения Winsock особенно важно. Дизайн, не учитывают взаимодействие Задержка подтверждения, алгоритм Nagle и буферизация Winsock может существенно сказаться на производительности. В статье рассматриваются эти проблемы, используя пару примеры внедрения и производный ряд рекомендаций для отправки пакетов данных небольшого эффективно из приложений Winsock.

Дополнительная информация

Фон

Получив пакет данных стека Microsoft TCP таймер задержки 200 мс погаснет. Когда подтверждение отправляется в конечном счете, таймер задержки будет сброшен и начнет другой 200 мс задержка при получении следующего пакета данных. Чтобы повысить эффективность приложений интрасети и Интернета, стек Microsoft TCP использует следующие критерии решить, когда следует отправлять одно подтверждение (ACK) для пакетов, полученных данных:
  • При получении второго пакета данных до истечения срока действия таймера задержки отправляется подтверждение (ACK).
  • При наличии данных, передаваемых в одном направлении как подтверждение (ACK) до получения второго пакета данных и срока действия таймера задержки, ACK piggybacked с сегмента данных и отправлено немедленно.
  • По истечении срока действия таймера задержки отправляется подтверждение (ACK).
Во избежание повторного congest сети небольших данных пакетов стека Microsoft TCP позволяет алгоритм Nagle по умолчанию объединяет буфера небольшой данные из нескольких вызовов send и задержки отправки, пока не будет отправлено подтверждение для предыдущего пакета данных адресатом с удаленного узла. Ниже приведены два исключения алгоритм Nagle.
  • Если стек совместно буфер данных больше чем максимальная данных (MTU), немедленно отправляется пакет полноразмерное без ожидания Подтверждения от удаленного хоста. В сети Ethernet MTU для протокола TCP/IP — 1460 байт.
  • Чтобы отключить алгоритм Nagle, небольшие пакеты доставляются на удаленный узел без задержек, применяется параметр сокета TCP_NODELAY.
Чтобы оптимизировать производительность на уровне приложения, буферов Winsock копии данных из приложения отправить вызовы Winsock буфера ядра. Затем стек использует собственную эвристику (например, алгоритм Nagle) для определения действительности поместить пакет по проводам. Можно изменить размер буфера ядра Winsock, выделенные для сокета, используя параметр «SO_SNDBUF» (это 8 K по умолчанию). При необходимости Winsock может буфера значительно больше, чем размер буфера SO_SNDBUF. В большинстве случаев Завершение отправки в приложение только указывает, что буфер данных в приложении отправить вызов будет скопировано в буфер ядра Winsock и не означает, что данные превысил средний сети. Единственное исключение — при отключении Winsock буферизации, задав SO_SNDBUF в 0.

Winsock использует следующие правила для обозначения завершения отправки в приложение (в зависимости от способа вызова отправить уведомление о завершении может быть функция, возвращающая в блокирующих вызовов сигналов события или вызова функции уведомления и так далее):
  • Если сокет будет находится в SO_SNDBUF квоты, Winsock копирует данные из приложения отправки и указывает на завершение отправки в приложение.
  • Если сокет находится за пределами SO_SNDBUF квот и только один ранее буфер отправки буфера стека ядра, Winsock копирует данные из приложения отправки и указывает на завершение отправки в приложение.
  • Если сокет находится за пределами SO_SNDBUF квот и существует несколько ранее в буфер отправки в стековом буфере ядра, Winsock копирует данные из приложения отправки. До завершения стек отправляет достаточно поместить сокета обратно в SO_SNDBUF квот или только одно условие, ожидающих отправки Winsock не означает завершение отправки в приложение.

Учебный пример: 1

Обзор:

Winsock TCP клиент должен отправить 10000 записей серверу Winsock TCP для хранения в базе данных. Размер записей зависит от 20 байт на 100 байт. Чтобы упростить логику приложения, структура выглядит следующим образом:
  • Клиент выполняет только блокировки отправки. Сервер выполняет блокировки полученного сообщения.
  • Клиентский сокет задает SO_SNDBUF 0, таким образом, чтобы каждая запись идет в сегменте данных single.
  • Сервер вызывает recv в цикле. Буфер, учтенные в recv составляет 200 байт, таким образом, чтобы каждая запись могут быть получены в вызове одной полученного сообщения.

Производительность:

Во время тестирования, разработчик находит сервер клиент может отправлять только пять записей в секунду. Всего 10 000 записей, максимальная в 976 КБ данных (10000 * 100 / 1024), занимает более половины часа для отправки на сервер.

Анализ:

Поскольку клиент не установлен параметр TCP_NODELAY, алгоритм Nagle вынуждает TCP стек ждать подтверждение, прежде чем он может отправлять пакеты другой по сети. Тем не менее клиент отключил Winsock буферизации, задав параметр SO_SNDBUF в 0. Таким образом, 10000 send вызывает имеют для отправки и ACK'ed по отдельности. Каждый ACK обусловлено задержкой 200 мс происходит в стеке TCP сервера:
  • Когда сервер получает пакет, его таймер задержки 200 мс погаснет.
  • Сервер не требуется отсылать ничего обратно, поэтому нельзя piggybacked подтверждение (ACK).
  • Клиент не будет посылать другого пакета, пока не подтверждены предыдущих пакетов.
  • Задержка на сервере истечения и подтверждение направляется обратно.

Как улучшить:

Существуют две проблемы с помощью этого конструктора. Во-первых существует проблема задержки таймера. Клиент должен иметь возможность отправить два пакета на сервер в 200-г-жа, поскольку клиент по умолчанию использует алгоритм Nagle, его следует просто использование буферизации по умолчанию Winsock и не равным 0, SO_SNDBUF. Когда стек TCP совместно буфер большего размера чем максимальное данных (MTU), немедленно отправляется пакет полноразмерное без ожидания Подтверждения от удаленного хоста.

Во-вторых этот конструктор вызывает одна отправка для каждой записи такого небольшого размера. Отправка небольшого размера не очень эффективно. В этом случае разработчик может потребоваться заполнить каждую запись на 100 байт и 80 записей во время от одного клиента send вызова. Чтобы узнать, сколько записей будет отправлено всего сервера, клиент может потребоваться для начала обмена данными с заголовком размера исправление, содержащее число записей, выполните.

Учебный пример: 2

Обзор:

Клиентское приложение Winsock TCP открывает два подключения с серверным приложением Winsock TCP службы котировки акций. Первое подключение используется в качестве канала команда отправить акции на сервер. Второе подключение используется как канал данных для получения котировок акций. После установления соединения двух клиент отправляет серверу через канал акции и ожидает возврата через канал данных котировки акций. Следующий запрос акции он отправляет серверу только после получения первого котировки акций. Клиент и сервер не установлен параметр SO_SNDBUF и TCP_NODELAY.

Производительность:

Во время тестирования, разработчик находит клиент может получить только пять квот в секунду.

Анализ:

Только такой подход позволяет один запрос неоплаченных котировок за один раз. Первый символ акции отправляется на сервер через канал (подключение) и ответ немедленно отправляется обратно с сервера на клиент по каналу передачи данных (подключение). Затем клиент немедленно отправляет второй запрос акции и отправки немедленно возвращает результат как запрос буфера в вызове send копируется в буфер ядра Winsock. Тем не менее стек TCP клиент не может отправить запрос из буфера ядра сразу, так как первый отправки через канал не подтверждены еще. После 200 мс задержки таймера на канал сервера истекает, подтверждение (ACK) для первого символа запроса возвращаются клиенту. Затем второй запрос квоты успешно отправлен на сервер после задержан г-200-жа квоту для второй символ акции возвращается немедленно через канал данных потому, что в настоящее время истек срок таймер задержки в клиентский канал данных. Подтверждение для предыдущего ответа квоты, полученных сервером. (Помните, что клиенту не удалось отправить второй запрос котировок акций для 200 мс, таким образом давая время задержки таймера на стороне клиента до истечения срока действия и отправить подтверждение (ACK) на сервере). В результате клиент получает ответ второго предложения и может выдавать другой запрос квоты, – того же цикла.

Как улучшить:

Дизайн два подключения (канал) здесь нет необходимости. Если использовать только одно подключение для запроса котировки акций и ответа ACK для запроса квоты можно piggybacked ответа квоты и немедленно вернуться. Для дальнейшего повышения производительности, клиент может «выступающий» несколько запросов котировок акций в один вызов отправки на сервер и сервер может также «выступающий» несколько ответов квоты в один вызов отправки клиенту. Если два канала Однонаправленная конструктора действительно необходимы для какой-либо причине, обе стороны должен установить параметр TCP_NODELAY, таким образом, небольшие пакеты могут быть переданы немедленно без необходимости ожидания Подтверждения для предыдущего пакета.

Рекомендации:

Эти две истории успеха составные, они позволяют продемонстрировать некоторые пессимистичным сценарием. При разработке приложения, которое включает в себя больших объемов данных небольшой сегмент отправляет и recvs, следует учитывать следующие рекомендации:
  • Если сегменты являются данные не критическая, приложение должно объединенных их в большего размера блока данных для передачи вызова send. Поскольку скорее всего, будет скопирован в буфер ядра Winsock буфера отправки буфера не должно быть слишком большим. Обычно действует немного меньше, чем 8 КБ. До тех пор, пока ядра Winsock Получает блок превышает MTU, он будет отправлять несколько пакетов полноразмерных и последний пакет с любой слева. Отправляющая сторона, за исключением последнего пакета, не будут выполнены, таймер задержки 200 мс. Последний пакет случае быть на нечетных пакет распространяется по-прежнему алгоритм Задержка подтверждения. Если отправка конца стека другого блока получает больше, чем значение MTU, он по-прежнему может обойти алгоритм Nagle.
  • По возможности избегайте соединения сокетов с однонаправленным данных потока. Связь через сокеты однонаправленным, легко охватывает Nagle и задержки подтверждения алгоритмов. Связь за запрос и ответ потока, следует использовать один разъем для отправки и recvs таким образом, чтобы ACK можно piggybacked ответа.
  • Если все сегменты небольшой данные отправляются немедленно, установите параметр TCP_NODELAY на отправителем.
  • Если не требуется гарантировать пакет отправляется по сети при завершении отправки обозначается Winsock, не следует задавать SO_SNDBUF к нулю. На самом деле 8 K буфера по умолчанию был эвристически идентифицировано подходит для большинства ситуаций и не изменяйте его пока не были проверены, нового буфера Winsock дает лучшую производительность, чем значение по умолчанию. Кроме того параметр SO_SNDBUF равным нулю в основном полезно для приложений, которые массовой передачи данных. Даже, для максимальной эффективности следует использовать в сочетании с двойной буферизации (несколько ожидающих отправки в любой момент времени) затем перекрывающегося ввода-вывода.
  • Если доставка данных не гарантируется, используют протокол UDP.

Ссылки

Для получения дополнительных сведений о задержки подтверждения и алгоритм Nagle можно найти следующее:

Braden, р. [1989] RFC 1122, требования к Интернет-узлов--уровни взаимодействия Интернет инженерных задач принудительно.

Свойства

Код статьи: 214397 - Последний отзыв: 4 июня 2011 г. - Revision: 4.0
Ключевые слова: 
kbdswnet2003swept kbapi kbinfo kbip kbnetwork kbwinsock kbmt KB214397 KbMtru
Переведено с помощью машинного перевода
ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.
Эта статья на английском языке:214397

Отправить отзыв

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com