简体   繁体   中英

Winsock 200ms delay issue

I find out it can be delay 200ms on WinSock send call

From MSDN: http://support.microsoft.com/kb/214397/en

Nagle Algorithm: http://en.wikipedia.org/wiki/Nagle 's_algorithm

Issue summary :

If send small msg(< MTU) with SO_SNDBUF "0" option repetedly, send function block 200ms.

My Question : Why first send message delay 200ms?

Because TCP is idle before first send call, I think first message must be sent immediately.

But Test result is not desired.

First message also delayed 200ms, why?

Thank you for answers.

Add some details :

Naggle algorithm work for small message like following:

1. if wire is idle, send it immediately.
2. if formal message's ACK is not received, wait until ACK & send
3. Window's TCP ack delay mechanism send ack after 200ms.

So, My expect is first message sends immediately and second message wait first message's ack for 200ms and so on.

Is this wrong?

Usually TCP keeps the data in the send buffer until it is acked by peer. In your case there isn't the send buffer (because of SO_SNDBUF=0). So TCP block the sender for keeping the data for possible retransmissions. TCP stack of the peer use the "Delayed ack" routine, and send acknowledge after 200ms delay (or until 2 packets with data is received without acking).

So the sender will be blocked until all data is acknowledged by peer. It may take more than 200ms if RTT of the network is long, or if packet lose occurs.

The whole point of the delay is to see if there's more data coming that could be added to the same message. There's no reason why the first message should be an exception to this rule.

The idea behind the Nagle algorithm is to optimize a case like that:

  1. You send 1 byte of data within a send() call
  2. After 1 msec you call send() again with 1 byte of data
  3. After 1 msec more you again call send()

Without the Nagle algorithm it would result in 3 separate packets each having several bytes of header and only 1 byte of useful payload. That would mean a lot of overhead.

With the Nagle algorithm the same sequence of send() calls will result in only 1 packet with some header bytes and 3 bytes of payload, thus, reducing the overhead size. However, the packet will be sent 200 msec after your first call.

The idea of the Nagle algorithm is to wait AFTER you send a small chunk of data expecting that you will probably want to send more. As the system does not know your future plans on sending anything, it waits a reasonable time (200 msec) and if nothing more is sent, it sends the actual packet not to make the delay too big.

The algorithm will benefit to your program if you send the data in small chunks without waiting for the reply (eg sending out a text file line-by-line). This will dramatically reduce the amount of packets sent over the network and the related overhead.

If your program is sensitive to response time and does not need this optimization, you can safely disable it by calling setsockopt() with the TCP_NODELAY argument or even consider using UDP instead of TCP.

Honestly I do not recall such behavior that the first message is also delayed. I worked with WinSock and the data was running smoothly. They can implement it this way because this is not against of any standard . This is the answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM