Не могу выключить 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, чтобы получить больше понимания об этом.