0
votes

I have a question about TCP behavior.

At receiver side, when the system call read() is slower than the TCP packets arrived rate, Does the packet loss and re-transmission occur?

I know the receive socket buffer overflow when it receive more packets than its size. But this is different from the above.


For finding the answer, I did a small experiment.

I generated lots of TCP packets from a sender host.

A receiver host read packet from its socket buffer.

I make this buffer value much smaller.

(ex. read(socket, buf, small_size) // small_size is 1kbyte

Then,

I found [PSH-ACK TCP packet] re-transmission occur at the receiver host.

Therefore, I decided that slow read() can make re-transmission. But I'm not sure.

Could you give me a little hint? Thank you so much!

1
It won't by itself cause retransmissions. Ultimately the sender will stall.user207421

1 Answers

3
votes

TCP protocol itself have several different mechanisms for handling bottlenecks. For example (google details):

  • Slow start
  • Flow control
  • Congestion control

Shortly: TCP stack uses windows for avoid sending more data to the peer than it can store to receiving queue.

When a sender try to send faster than network/receiver can handle, the output queue of TCP stack of the sender will fill up. When the queue is full, then the sender notices this by few ways:

  • with blocking socket: send() call will block.
  • with unblocking socket: send() call will fail with errno EAGAIN or EWOULDBLOCK.
  • whith select() call: writefd-set won't indicate writing possibility.

This way the TCP stack can automatically slow down the sender, and so minimize packet lost in network/receiving end.

EDIT:

Tcpdump example, where server (B) does not call recv() after accept():

~ # tcpdump -i eth0 "tcp port 12345"
21:44:16.255183  A > B:  seq 2052761822, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
21:44:16.255484  B > A:  seq 2110966471, ack 2052761823, win 7300, options [mss 1460,nop,nop,sackOK], length 0
21:44:16.256065  A > B:  ack 1, win 64240, length 0
21:44:20.338089  A > B:  seq 1:1461, ack 1, win 64240, length 1460
21:44:20.338365  B > A:  ack 1461, win 5840, length 0
21:44:20.338754  A > B:  seq 1461:2921, ack 1, win 64240, length 1460
21:44:20.338978  B > A:  ack 2921, win 5840, length 0
21:44:20.339357  A > B:  seq 2921:4381, ack 1, win 64240, length 1460
21:44:20.339759  A > B:  seq 4381:5841, ack 1, win 64240, length 1460
21:44:20.340175  A > B:  seq 5841:7301, ack 1, win 64240, length 1460
21:44:20.340571  A > B:  seq 7301:8761, ack 1, win 64240, length 1460
21:44:20.373395  B > A:  ack 8761, win 1460, length 0
21:44:20.374367  A > B:  seq 8761:10221, ack 1, win 64240, length 1460
21:44:20.413398  B > A:  ack 10221, win 0, length 0
21:44:20.714460  A > B:  seq 10221:10222, ack 1, win 64240, length 1
21:44:20.714725  B > A:  ack 10221, win 0, length 0
21:44:21.314796  A > B:  seq 10221:10222, ack 1, win 64240, length 1
21:44:21.315055  B > A:  ack 10221, win 0, length 0
21:44:22.515652  A > B:  seq 10221:10222, ack 1, win 64240, length 1
21:44:22.515925  B > A:  ack 10221, win 0, length 0
21:44:24.917211  A > B:  seq 10221:10222, ack 1, win 64240, length 1
21:44:24.917473  B > A:  ack 10221, win 0, length 0
21:44:29.718352  A > B:  seq 10221:10222, ack 1, win 64240, length 1
21:44:29.718612  B > A:  ack 10221, win 0, length 0
21:44:39.331520  A > B:  seq 10221:10222, ack 1, win 64240, length 1
21:44:39.331789  B > A:  ack 10221, win 0, length 0

The client (A) tries to send big segments to server (B) until the server starts advertise window size 0. After this point the client (A) start using segment size 1 byte, and period between re-transmission start increasing. It looks like, that TCP stack tries to minimize traffic that is needed for polling the window.

RFC-793 says the following (Later RFCs may specify this better):

The sending TCP must be prepared to accept from the user and send at least one octet of new data even if the send window is zero. The
sending TCP must regularly retransmit to the receiving TCP even when
the window is zero. Two minutes is recommended for the retransmission interval when the window is zero. This retransmission is essential to guarantee that when either TCP has a zero window the re-opening of the window will be reliably reported to the other.

When the receiving TCP has a zero window and a segment arrives it must still send an acknowledgment showing its next expected sequence number and current window (zero).