Networking question

Chris Johns chrisj at rtems.org
Mon May 5 06:03:36 UTC 2008


Leon Pollak wrote:
> On Saturday, 3 בMay 2008, Chris Johns wrote:
>>> The problem occurs in about 70% of the cases when on the other side (PC
>>> with Windows XP) user cancels the application.
>> When a remote socket is closed the local socket read will return with a
>> length of 0. This means the socket has died. I suggest you check for this
>> and flag to the sending tasks not to send anything more into the socket.
> This is what I do already. Thanks.
> But this does not help...

Great. I mentioned this is due to you saying the read returned with -1. 
Returning the length 0 will not have an error, ie it return 0 rather than -1.

> 
>>> Very nice, except that there are other 70%, when the "read" operation
>>> ends with -1, while almost all send's do not (some times one does).
>>> When I dump out the tasks states in the bad case, I see that all these
>>> are waiting for events (which is not my case, as I do only
>>> rtems_task_wake...).
>> This is the way the socket implementation works. The socket has blocked the
>> sender. I suspect not enough space to write the data into so your tasks are
>> blocked.
> Hmmm..... Why?
> I was sure that the problem is (as this is TCP not UDP) in that the remote 
> socket does not send acknowledge and therefore sending blocks.
> 
> What you say is that send(so,...) will not block (if there is enough space) 
> even without acknowledge?
> 

I am not sure what you term the remote socket. My point of reference is the 
RTEMS target, ie local, and the PC remote.

Lets start this analysis over. I am assuming you have a unidirectional data 
transfer from the RTEMS device to the PC. You need to set the sending buffer 
size on the RTEMS side and the receive buffer size on the PC. The receive 
buffer size sets the window size for the pipe.

Consulting Steven's Network Programming Vol 1, Section 7.5:

  "The capacity of the pipe is called the *bandwidth-delay product* and we
   calculate this by multiplying the bandwidth (in bits/sec) times the RTT
   (round-trip time, in seconds), converting the result from bits to bytes."

The RTT can be determined from the results of ping. Stevens then states:

  "If the socket buffer sizes are less than this, the pipe will not stay
   full, and performance will be less than expected."

If the buffer sizes are not correct the pipe will not be full and your send 
may end up blocking. Increasing the buffer size so you operate below the 
pipe's limit should stop the sends blocking. This was the point I was poorly 
attempting to make before.

Another issue is the sending side must have a send buffer capacity large 
enough to hold a copy of the data until the acks have been received. This is 
not the socket send buffer but the buffers in the network stack. A dead lock 
could occur if you have so much sent data you have no buffers to receive the 
acks with.

A simple way to check if a send will block is to place the socket into 
non-blocking mode and to report when the send fails. The receive can use 
select to see if data has arrived.

> 
>> Do not close the socket with tasks in socket calls. That is do not close
>> the socket from the read task when you read 0 bytes until all sending tasks
>> have returned. This will result in a crash.
> Hmmm!
> This does not crash in my case but simply hangs on waiting for events.
> 
> I was sure that closing the socket while it is in the sending process will 
> abort waiting for ack, while further sendings will be ignored.
> But you say - this is incorrect assumption.

I was referring to an RTEMS implementation issue I raised back in May 2005 
along with PR785:

http://www.rtems.com/ml/rtems-users/2005/may/msg00027.html

As stated I had not checked all system call paths but I seem to remember 
problems existing in a number of places. The send maybe ok or it may not. The 
patch may fix the blocking issue.

As to the normal behaviour when threads are in a socket and the socket is 
closed I seem to remember the behaviour on BSD and Linux being different and I 
cannot remember what the behaviour was. I prefer the threads to return with an 
error code.

Regards
Chris



More information about the users mailing list