RTCS send function blocks on send for missing socket devices

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

RTCS send function blocks on send for missing socket devices

749 Views
mmiller
Contributor I

Hi,

I've got an application where I'm serving data to connected devices (ipads, droid tablets) so that they can update their user interfaces to reflect the system state.  So whenever the system state changes, I go through all connected sockets and send the updated data:

result = send(socketHandle, dataPtr. dataLength, 0);

And everything works great.  However, I find that if one of my connected devices loses the socket ungracefully (for example, changing wifi networks on the ipad), my application will continue to send the updates, and result will continue to show the proper number of bytes sent.  Eventually, I'm guessing once the tx buffer is filled, the send command blocks.  This is the only indication I have that the message was not actually sent.

I've tried changing the socket options for OPT_SEND_NOWAIT, but it doesn't seem to affect this behavior.

It may be relevant to note that if the missing client returns to the network, the send unblocks and all previous messages are sent.

Likewise, I've found if, after the send blocks, I use a separate task to send a:

shutdown(socketHandle, FLAG_ABORT_CONNECTION);

... the task containing the send unblocks.

One final piece of information - when the client closes the socket normally, my task that reads for data on the socket gets a RTCS_ERROR in its:

result = recv(...)

... and performs its own shutdown.  So I only appear vulnerable to sockets that I think are still open, but the device isn't actually connected any longer.

So my question:  is there a methodology of determining if the message packet has actually been sent?  Maybe a way to see how full the tx buffer is before calling send?  Or alternatively, do I need a supervisory task to monitor for this blocked condition and force the socket shutdown?

Thanks for the help - please let me know if more information would help.

Matt

Labels (1)
0 Kudos
1 Reply

293 Views
Martin_
NXP Employee
NXP Employee

Hi Matt,

I'm afraid that detection of an outbound TCP packet being sent is not enough, as a remote peer has to acknowledge the data (ACK) and only after that, the acknowledged amount of data is removed from the send buffer. If there is no acknowledge from the remote peer, the data sits in the send buffer, waiting for the link renewal, and there are also retransmission attempts after retransmission timeout.

you may check this

Re: FNET - TCP/IP Stack

There is a timeout, when the stack detects a segment has not been acknowledged for certain time, the stack will shut down the socket connection. This is OPT_CONNECT_TIMEOUT, default is 8 minutes and there might be also some minimum required by the RFC.

In RTCS there is a possibility to use TCP send with OPT_SEND_WAIT socket option. This option is not documented in the current RTCS User's guide, but it is implemented in the source code (next RTCS version will fix this by introducing new flag for the send() function).

When the two socket options OPT_SEND_WAIT=TRUE and OPT_SEND_NOWAIT=FALSE, then the send() requester would block until all data sent & acknowledged. Now, perhaps you can use OPT_SEND_TIMEOUT to configure, how much time the send() function would block.

If this timeout expires and send() returns less bytes sent&ack'ed than requested, your task might initiate shutdown of the socket.

-Martin

0 Kudos