Когда я должен использовать TCP_NODELAY, а когда TCP_CORK? - PullRequest
57 голосов
/ 21 сентября 2010

Я понял, что оба они отключают алгоритм Нейгла.

Когда я должен / не должен использовать каждый из них?

Ответы [ 4 ]

69 голосов
/ 15 ноября 2013

Прежде всего, не оба они отключают алгоритм Нейгла.

Алгоритм Nagle предназначен для уменьшения большего количества небольших сетевых пакетов в сети. Алгоритм таков: если данные меньше предела (обычно MSS), дождитесь получения ACK для ранее отправленных пакетов и в то же время накапливайте данные от пользователя. Затем отправьте накопленные данные.

if [ data > MSS ]
    send(data)
else
    wait until ACK for previously sent data and accumulate data in send buffer (data)
    And after receiving the ACK send(data)

Это поможет в таких приложениях, как telnet. Однако ожидание ACK может увеличить задержку при отправке потоковых данных. Кроме того, если получатель реализует «отложенную политику ACK», это приведет к временной тупиковой ситуации. В таких случаях лучше отключить алгоритм Нейгла.

Таким образом, TCP_NODELAY используется для отключения алгоритма Нейгла.

TCP_CORK активно накапливает данные. Если в сокете включен TCP_CORK, он не будет отправлять данные, пока буфер не заполнится до фиксированного предела. Подобно алгоритму Nagle, он также накапливает данные от пользователя, но до тех пор, пока буфер не заполнится до фиксированного предела, а не до получения ACK. Это будет полезно при отправке нескольких блоков данных. Но вы должны быть более осторожны при использовании TCP_CORK.

До версии 2.6 оба эти параметра являются взаимоисключающими. Но в более позднем ядре они оба могут существовать вместе. В таком случае TCP_CORK будет отдано больше предпочтений.

Ref:

21 голосов
/ 24 июля 2014

TCP_NODELAY

Используется для отключения алгоритма Нейгла для улучшения сетей TCP / IP и уменьшения количества пакетов путем ожидания получения подтверждения ранее отправленных данных для отправки накопленных пакетов.

// Из руководства по tcp (7):

TCP_CORK (или TCP_NOPUSH во FreeBSD)

Если установлено, не отправлять частичные кадры. Все поставленные в очередь частичные кадры отправляются при повторной очистке опции. Это полезно для добавления заголовков перед вызовом sendfile(2) или для оптимизации пропускной способности. Как в настоящее время реализовано, существует ** 200-миллисекундный потолок ** на время, для которого выходные данные закупорены на TCP_CORK. Если этот потолок достигнут, данные из очереди автоматически передаются . Эта опция может быть объединена с TCP_NODELAY только начиная с Linux 2.5.71. Эта опция не должна использоваться в коде, предназначенном для переносимости.

7 голосов
/ 21 сентября 2010

Это оптимизация, как и любая оптимизация:

  1. Не используйте его
  2. Подождите, пока производительность не станет проблемой, затем определите, что задержка сокета определенно является причиной этого, и тестирование доказывает, что это определенно исправит это, И это самый простой способ исправить это, сделать это.

По сути, цель состоит в том, чтобы избежать отправки нескольких кадров, где можно использовать один кадр, с sendfile () и его друзьями.

Так, например, на веб-сервере вы отправляете заголовки, а затем содержимое файла, заголовки собираются в памяти, а затем файл отправляется непосредственно ядром. TCP_CORK позволяет отправлять заголовки и начало файла в одном кадре, даже с TCP_NODELAY, что в противном случае немедленно отправило бы первый чанк.

0 голосов
/ 25 ноября 2012

TCP_CORK является противоположностью TCP_NODELAY. Первый форсирует задержку накопления пакетов; последний отключает его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...