Reputation: 2318
So, I was going through TCP stuff when I came across Nagle's algorithm and delayed ACKs for small sized packets (1 byte data). The reason being, avoiding to send lot of small packets on the network (Nagle) and piggybacking data(Delayed ACK). There was however, no mention about these algorithms for bulk data, i.e I do a write of > 8000 bytes. 4 questions:
Is these algorithms only applicable for small sized packets?
For ex, when we do a write(8000), TCP first sends 1500 bytes (Assume 1500 to be MSS and slow start is happening) , before an ACK is received for the first, it can send another 1500 bytes of data, then isn't violating Nagle's?
Does the receiver wait for the timeout to send a delayed ACK or does it send immediately after receiving 1500 bytes of data?
How does it know when to delay an ACK? Is it based on the bytes in its receive buffer?
Thanks!
Upvotes: 31
Views: 8093
Reputation: 875
The idea of the Nagle algorithm was to prevent more than one undersized packet from being in transit at a time. The idea of delayed ACKs (which came from Berkeley) was to avoid sending a lone ACK for each character received when typing over a Telnet connection with remote echo, by waiting a fixed period for traffic in the reverse direction upon which the ACK could be piggybacked.
The interaction of the two algorithms is awful. If you do big send, big send, big send, that works fine. If you do send, get reply, send, get reply, that works fine. If you do small send, small send, get reply, there will be a brief stall. This is because the second small send is delayed by the Nagle algorithm until an ACK comes back, and the delayed ACK algorithm adds 0.5 second or so before that happens.
A delayed ACK is a bet. The TCP implementation is betting that data will be sent shortly and will make it unnecessary to send a lone ACK. Every time a delayed ACK is actually sent, that bet was lost. The TCP spec allows an implementation to lose that bet every time without turning off delayed ACKs. Properly, delayed ACKs should only turn on when a few unnecessary ACKs that could have been piggybacked have been sent in a row, and any time a delayed ACK is actually sent, delayed ACKs should be turned off again. There should have been a counter for this.
Unfortunately, delayed ACKs went in after I got out of networking in 1986, and this was never fixed. Now it's too late.
John Nagle
Upvotes: 91
Reputation: 151
Nagle is turned off through socket option. Both Nagle and Delayed ack are set by default. Nagle delays the transmission unless a full packet is formed or there are unacked data in the pipe, so, it influences the performance of application limited flow with small packets.
It Depends on the send pattern
If there is already an unacked packet at the receiver, this 1500 bytes will make an ack. However if there is no prior received data and the receiver is not using quick ack, sending ack will be delayed for some time (e.g. 200 ms) or unless the next packet is received.
Number 3 will help.
Upvotes: 0
Reputation: 33592
Nagle's algorithm is supposed to reduce the number of small packets (e.g. so it doesn't send individual packets for each character you type into telnet over a slow link). If it can send a full packet, it should send a full packet. It does not violate the description in RFC 1122 section 4.2.3.4:
If there is unacknowledged data (i.e.,
SND.NXT > SND.UNA
), then the sending TCP buffers all user data (regardless of the PSH bit), until the outstanding data has been acknowledged or until the TCP can send a full-sized segment (Eff.snd.MSS
bytes; see Section 4.2.2.6).
Delayed ACKs reduce the number of packets sent in the reverse direction, but the description in RFC 1122 leaves a lot up to the implementation:
A TCP SHOULD implement a delayed ACK, but an ACK should not be excessively delayed; in particular, the delay MUST be less than 0.5 seconds, and in a stream of full-sized segments there SHOULD be an ACK for at least every second segment.
Note that while you are sending "bulk data", the receiver isn't! If it sent immediate ACKs, they'd all be small packets which can have a lot of overhead.
Upvotes: 1