I’m writing a TCP client that connect to a server and send data periodically. The server isn’t supposed to answer with an ACK (and I can’t change it).
I open the client socket as a blocking one and get send() return that it’s supposed to be the number of bytes sent. All works perfect until I unplug the server ethernet wire, the send function return a valid number of written bytes although obviously it isn’t.
If server side close connection with close() doing a send() at the client return -1 (it works). It only “fails” when I unplug the wire.
Somethings I try but doesn’t work:
Set socket as non-blocking and select() it to know if write is possible. It says me it’s although it isn’t.
poll() for POLLOUT event. Same as above.
Set SNDBUFF to 0.
The only way I got it working is doing “Open-Send-Close” because when I try to reopen a non-connected server it warn me. But I want to avoid doing that if possible. Is there any way to know if destination of a open socket it’s up?
I believe the behaviour is valid. When the cable is removed, TCP/IP protocol assumes a problem on the network and tries to send the packet again after a certain time.
Unfortunately that’s not possible with just plain TCP/IP.
This is why protocols were invented that send back acknowledgements that messages arrived.
The TCP/IP stack is designed to buffer packets for 30-40 seconds to handle temporary network cable disruptions.
You can try setting the SO_SNDTIMEO to a small value (less than a second) and that should cause the send() call to return with an error. Of course this may not actually be implemented under QNX because this is apparently one of the most widely non supported socket options.
This brings back memories. On one of my first projects involving QNX and TCP/IP I had the exact same surprise. We had two computers connected via TCP/IP and after unplugging the cable, the send() still returned without an error.
This is the correct behavior. Crazy as it sounds. TCP/IP provides no ACK or timeout to the user. What it provides is a guarantee that any packets you send will either appear correctly at the receiving end, or not at all.
If you do not like this, and you cannot add your own timeout/ACK then you are SOL.