views:

262

answers:

4

Hi

I have a problem - when I'm trying to send huge amounts of data through posix sockets ( doesn't matter if it's files or some data ) at some point I don't receive what I expect - I used wireshark to determine what's causing errors, and I found out, that exactly at the point my app breaks there are packets marked red saying "zero window" or "window full" sent in both directions.

The result is, that the application layer does not get a piece of data sent by send() function. It gets the next part though...

Am I doing something wrong?

EDIT:

Lets say I want to send 19232 pieces of data 1024 bytes each - at some random point ( or not at all ) instead of the 9344th packet I get the 9345th. And I didn't implement any retransmission protocol because I thought TCP does it for me.

A: 

Does in your network iperf also fails to send this number of packets of this size? If not check how they send this amount of data.

skwllsp
A: 

Hm, from what I read on Wikipedia this may be some kind of buffer overflow (receiver reports zero receive window). Just a guess though.

Space_C0wb0y
+1  A: 

Zero Window / Window Full is an indication that one end of the TCP connection cannot recieve any more data, until its client application reads some of the data is has already recieved. In other words, it is one side of the connection telling the other side "do not send any more data until I tell you otherwise".

TCP does handle retransmissions. Your problem is likely that:

  1. The application on the recieving side is not reading data fast enough.
  2. This causes the recieving TCP to report Window Full to the sending TCP.
  3. This in turn causes send() on the sending TCP side to return either 0 (no bytes written), or -1 with errno set to EWOULDBLOCK.
  4. Your sending application is NOT detecting this case, and is assuming that send() sent all the data you asked to send.

This causes the data to get lost. You need to fix the sending side so that it handles send() failing, including returning a value smaller than the number of bytes you asked it to send. If the socket is non-blocking, this means waiting until select() tells you that the socket is writeable before trying again.

caf
+1  A: 

First of all, TCP is a byte stream protocol, not a packet-based protocol. Just because you sent a 1024 byte chunk doesn't mean it will be received that way. If you're filling the pipe fast enough to get a zero window condition (i.e., that there is no more room in either a receive buffer or send buffer) then it's very likely that the receiver code will at some point be able to read far more at one time than the size of your "packet".

If you haven't specifically requested non-blocking sockets, then both send and recv will block with a zero window/window full condition rather than return an error.

If you want to paste in the receiver-side code we can take a look, but from what you've described it sounds very likely that your 9344th read is actually getting more bytes than your packet size. Do you check the value returned from recv?

Chris Cleeland