Не могу выключить TCP_NODELAY

Я использую Boost asio для отправки TCP-сообщения. Я установил опцию NO_DELAY, потому что это система управления в режиме реального времени. Я вижу флаг PSH, установленный в сообщении с помощью Wireshark. Я доволен производительностью, и она работает, как и ожидалось.

Для интереса я решил отключить NO_DELAY и измерить разницу в производительности.

Я поменял свой существующий код:

m_tcpSocket.open(boost::asio::ip::tcp::v4());
boost::asio::ip::tcp::no_delay noDelayOption(true);
m_tcpSocket.set_option(noDelayOption);

// snip create endpoint
m_tcpSocket.connect(m_tcpServerEndpoint);

// snip build message
m_tcpSocket.send(boost::asio::buffer(pDataBuffer, size));

за

boost::asio::ip::tcp::no_delay noDelayOption(false);
m_tcpSocket.set_option(noDelayOption);

и я все еще вижу установленный флаг PSH.

Я также попытался удалить код set_option и все еще вижу его установленным.

В Wireshark я вижу:

104 - 105  SYN
105 - 104  SYN, ACK
104 - 105  ACK
104 - 105  PSH, ACK + my message
105 - 104  ACK

где 104 и 105 - IP-адреса моих двух компьютеров. Я также удивлен, что сообщение с моими данными имеет ACK.

Как отключить NO_DELAY?

2 ответа

Решение

Ваш код выглядит так, как будто он правильно настроен TCP_NODELAY вкл или выкл. Установить TCP_NODELAY выкл, используйте:

socket.set_option(boost::asio::ip::tcp::no_delay(false));

TCP RFC определяет PSH как функцию push. Короче говоря, это флаг, который информирует получателя о том, что все данные были отправлены, поэтому перенаправляйте данные в стек протоколов. Boost.Asio отображает свой API на сокеты BSD, а сокеты BSD не обеспечивают способ управления флагом PSH. Это часто обрабатывается ядром в стеке протоколов, когда он очищает свой буфер.

Из проиллюстрированного TCP/IP:

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

[...]

Нажмите (получатель должен передать эти данные приложению как можно скорее - ненадежно реализовано или использовано).

NO_DELAY не изменяет флаги, которые отправляются на одноранговый узел. Изменяет алгоритм буферизации ядра. Google о алгоритме Nagle, чтобы получить больше понимания об этом.

Другие вопросы по тегам