Многочисленный результат обменов небольшого пакета в плохой производительности TCP
Q: Мое приложение TCP обменивается многими небольшими пакетами информации, которая может или может не генерировать ответ с другой стороны. В некоторых случаях я нахожу, что задержки приложения, отправляющие пакеты и производительность, ужасны. Как я могу решить эту проблему?
A: Одной возможной причиной этого поведения является алгоритм Nagle, который является функцией TCP, работающего для предотвращения отправлять-стороны 'глупый синдром окна'. Если соединение TCP будет иметь неподтвержденные данные, то алгоритм Nagle предотвратит передачу новых данных с целью быть для объединения большого количества небольших пакетов данных в один большой. Например, если приложение генерирует данные один байт за один раз, этот алгоритм препятствует тому, чтобы он заполнил сеть большим количеством однобайтовой полезной нагрузки пакеты TCP.
В большинстве случаев алгоритм Nagle является хорошей вещью, и необходимо оставить его, включил. Так, прежде, чем отключить алгоритм Nagle, необходимо проверить использование TCP эффективно. В частности удостоверьтесь, что Вы представляете свои данные TCP как целые логические единицы. Например, если Ваши данные состоят из заголовка, сопровождаемого организацией, не пишите заголовок и затем пишите организацию. Скорее свяжите все в один единственный буфер и запишите все это сразу (альтернативно, можно использовать функцию, такую как sendmsg, поддерживающий несмежные записи). Это будет препятствовать тому, чтобы алгоритм Nagle задержал организацию излишне. Короче говоря, при использовании TCP эффективно Вы могли бы найти, что это решает Вашу проблему, и Вы не должны волноваться об алгоритме Nagle вообще.
Однако для некоторых приложений — особенно интерактивных приложений, как telnet — алгоритм Nagle может вызвать ненужные задержки. Если это так, можно отключить его на определенном соединении путем установки TCP_NODELAY опция сокета, как показано в Перечислении 1.
Перечисление 1 , Устанавливающее опцию TCP_NODELAY
int err; static const int kOne = 1; err = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &kOne, sizeof(kOne)); if (err < 0) { err = errno; } |
При использовании высокоуровневого TCP API, как NSStream или CFStream, можно отключить алгоритм Nagle первым получением дескриптора файла от потокового использования kCFStreamPropertySocketNativeHandle и затем вызов setsockopt на том дескрипторе.
История версии документа
| Дата | Примечания |
|---|---|
| 09.09.2011 | Обновленный, чтобы описать Сокеты BSD, а не Открыть Transport. |
| 25.05.1998 | Новый документ, объясняющий, почему многочисленный небольшой пакет обменивается результатом в плохой производительности TCP. |