2

I'm using Boost asio to send a TCP message. I set the NO_DELAY option because this is a 'real time' control system. I see the PSH flag set in the message using Wireshark. I am happy with the performance and it is working as expected.

For interest, I decided to turn the NO_DELAY off and measure the performance difference.

I swapped my existing code:

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));

for

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

and I still see the PSH flag set.

I also tried removing the set_option code and still see it set.

In Wireshark I see:

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

where 104 and 105 are IP addresses of my 2 PCs. I am also surprised that the message with my data has an ACK.

How do I turn NO_DELAY off?

Ant
  • 1,668
  • 2
  • 18
  • 35

2 Answers2

6

Your code looks as though it is properly setting TCP_NODELAY on or off. To set TCP_NODELAY off, use:

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

The TCP RFC defines PSH as the push function. In short, it is a flag that informs the receiver that all data has been sent, so forward data up the protocol stack. Boost.Asio maps its API to BSD sockets, and BSD sockets do not provide a way to control the PSH flag. This is often handled by the kernel within the protocol stack, when it clears its buffer.

From TCP/IP Illustrated:

This flag is conventionally used to indicate that the buffer at the side sending the packet has been emptied in conjunction with sending the packet. In other words, when the packet with the PSH bit field set left the sender, the sender had no more data to send.

[...]

Push (the receiver should pass this data to the application as soon as possible—not reliably implemented or used).

Community
  • 1
  • 1
Tanner Sansbury
  • 51,153
  • 9
  • 112
  • 169
  • Thank you, it was setting TCP_NODELAY on or off that I really needed to know so I've marked this as the correct answer. I thought there was a direct correlation between the setting and the push flag and now understand there isn't. I now presume that if I have a large amount of data to send and have TCP_NODELAY turned off then the socket may break the data down into a number of packets and the I could expect the last of those packets to have the PSH flag set. – Ant Mar 15 '13 at 14:54
2

NO_DELAY does not change flags that is sent to peer. It changes kernel's buffering algorithm. Google about Nagle algorithm to get more understanding about it.

Galimov Albert
  • 7,269
  • 1
  • 24
  • 50
  • I have been reading about Nagle and also the effects of NO-DELAY and although I know you can't rely on everything you find on the Internet I gathered the impression that the push flag was set so that there was also no delay at the peer end. Have I got that wrong? – Ant Mar 08 '13 at 17:29
  • @Ant Nagle is delay before sending, its nothing to do at the peer end. – Galimov Albert Mar 08 '13 at 17:59
  • Ok, I understand now. I thought there was a direct correlation between NO_DELAY and the PSH flag. – Ant Mar 15 '13 at 14:51