TCP server question

Hello.

I know this is not really a question about qnx, but I have read about it in tcp books and I dont find the solution to my problem. I wuld be really grateful if someone could help me.

I have written a TCP server in QNX 6.2.1 SE. The server can work in two modes. In one of the modes, if the client send a command to the server, the server will then send cyclically parameters to the client (without any confirmation or answer) from the client.
If the cable between the server and the client is unplugged in this mode, the write command doesnt give me any error. If the cable is plugged again, the connection is my server is still in ESTABLISHED state although the client has closed the socket. KEEPALIVE detects this situation, but it needs too much time for my application.

My questions are:

Is there a quick way (10, 30 seconds time maximum) for the server to detect this situation?
Does the write command or any command used to send data with a socket, reply with any error in this situation? I have tried using select and write, but they dont give me any error.

Thank you very much in advance.

use setsockopt() to configure timeouts.
if you are using NONBLOCKING sockets - then you’ll be notified of connection failure the next time you try to send or recieve data on the socket. If you are using BLOCKING socket - you’ll be notified immediately on return from send()/sendto() by errno.

Thank you Mike.
I am using blocking sockets. I have used SO_RCVTIMEO with the read operation and it works. But i have configured SO_SNDTIMEO with the write operation and the timeout doesnt work. I mean, the write operation works without any problem (no detection of the cable unplugged).

I am using write instead of send o sento. I dont know if this could be the problem. And the return of “write” doesnt tell me any error (it returns the number of bytes written, independently if the cable is plugged or unplugged).

I post the code in which I use the write function (fd is the socket descriptor)

int F_Write_TCP(int fd, const void *vptr, int n)
{
int nleft; // Number of bytes left
int nwritten;// Number of bytes written
const char *ptr;// Pointer to the string to send

ptr=vptr;	//Pointer to the string
nleft= n;	//Number of bytes to write

while (nleft > 0) // While all bytes are not written
{
   nwritten= write(fd, ptr, nleft);
	
   if (nwritten <= 0)	// End of bytes written
  {
     if (nwritten < 0 && errno == EINTR)
         nwritten= 0;	// Write again
     else
          return(-1);  //	Error
   }

   nleft -= nwritten;	// Number of bytes left to write
   ptr += nwritten;	// Points to the new position
}

return (n);	     //Number of bytes returned

}

Thank you very much in advance.

hm…
That is what help says about send()

No indication of failure to deliver is implicit in a send()

I suppose send() and write do not differ much on a connected socket.
I have to check what happens to my app in this case (in case cable is unplugged and host is unreacheble).

In case the cable was unplugged at the client side you cannot actively detect in any way the connection is alive or dead.

The TCP driver will close the connection after retransmition timeouts, but the timeout would be 2 minutes on implementations based on BSD sockets.

Only way I see to detect that cable was unplugged at the client side (or client machine crashed, or TCP driver on client was stopped) is to implement some acknowledge or hearthbeat in the application protocol, otherwise you gonna wait 2 minutes for system timeout.

TCP is a “reliable” protocol. “reliable” means, if a packet is lost, it will wait, retry, hope the situation will recover. Only if after certain time wait/number of retry, TCP will give up and report errors back to application. This time period, typically is 9.5 minutes if I remember correct.

The fact “cable is unplug” is a link layer thing, tcpip protocols don’t depends on Link layer.

Your best bet (from protocol layer), is sending all those “cyclically parameters to the client” through UDP.

Please, can you explain why 9.5 minutes?
By 2 minutes I meant the MSL (Maximum Segment Lifetime) which, by the way, I cannot find in the sysctl in net.inet.tcp on 6.2.1 and can you tell us what is the timeout in qnx4 in tcp425 and tcp5 ?

Please correct me if I am wrong to assume the MSL is not used to determine connection down state.

Thank you for your answers.

I have tried a solution for my problem, it seems to work but I dont know if it is ok. I show you my solution.

The server can send between 200 and 600 bytes each two seconds in the mode I have explained you.

I have set the SO_SNDLOWAT parameter only few bytes less than the SO_SNDBUF size.

I have use select with a timeout (1 second) blocking in the socket descriptor to become writeable.

If the cable is plugged, everythink works fine but if the cable is unplugged, the send buffer grows (because the client doesnt read the data) and when the buffer grows more than (SO_SNDBUF-SO_SNDLOWAT) bytes, select detects the situation (socket not writeable), and gives me a timeout. With this approach I can detect that the cable is unplugged.

Are you agree with this approach?

Thank you again.

xtang: For me it is not possible to change to UDP.