TCP Socket Server

Have a TCP/IP server that manages up to 32 (1 listen + 31 potential
clients)descriptors underneath a QNX4 select Receive(). When the peer drops
their application the descriptor becomes ready and read for zero bytes–a
typical disconnection. However, if the peer does not properly shutdown the
socket (i.e. peer cold boot) I never get any notification that the they have
disconnected. Netstat show connection as still being established. I have
tried enabling SO_KEEPALIVE whereby keepalive probes are sent but I still am
not getting desired results. Any suggestions?

David F. Marker
Interpro Technology, Inc.
interprotech@ameritech.net

Previously, David F. Marker wrote in qdn.public.qnx4:

Have a TCP/IP server that manages up to 32 (1 listen + 31 potential
clients)descriptors underneath a QNX4 select Receive(). When the peer drops
their application the descriptor becomes ready and read for zero bytes–a
typical disconnection. However, if the peer does not properly shutdown the
socket (i.e. peer cold boot) I never get any notification that the they have
disconnected. Netstat show connection as still being established. I have
tried enabling SO_KEEPALIVE whereby keepalive probes are sent but I still am
not getting desired results. Any suggestions?

David F. Marker
Interpro Technology, Inc.
interprotech@ameritech.net

TCP/IP timeouts are long, in the range of 5 to 15 minutes. You will
eventually get a disconnect, just not in the time frame that you want
it. Not all socket implementations support SO_KEEPALIVE, and even if
they do, they might not do what you want. To learn about an abnormal
disconnect on the other end, you really need to implement your own
heartbeat on the socket. Keep a timer that ticks regularly on both
sides, and if they have not sent any data since the last tick, send a
NOP packet. Of course, you have to define what a NOP packet is, and
recognize it in both programs. Now, in both programs, keep another
timer that looks to see if data has arrived since the last tick. If N
ticks pass without data arriving, the other program is dead.

This may sound like a pain, which it is, but that’s the world of
TCP/IP. It was never designed to be speedy in the face of abnormal
termination - it was meant to be robust in unreliable networks.

Cheers,
Andrew

David F. Marker <interprotech@ameritech.net> wrote:

Have a TCP/IP server that manages up to 32 (1 listen + 31 potential
clients)descriptors underneath a QNX4 select Receive(). When the peer drops
their application the descriptor becomes ready and read for zero bytes–a
typical disconnection. However, if the peer does not properly shutdown the
socket (i.e. peer cold boot) I never get any notification that the they have
disconnected. Netstat show connection as still being established. I have
tried enabling SO_KEEPALIVE whereby keepalive probes are sent but I still am
not getting desired results. Any suggestions?

Are you sure the keepalive probe is send out? Be default, it will
only send out after 2 hours idle. You need TCP_KEEPALIVE to change
that 2 hours. Also, it take about 10min to probe and decided to
drop the link.

Below is a little small program I used to test these things.

-xtang

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/types.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>

#ifndef TCP_KEEPALIVE /* should be defined in netinet/tcp.h */
#define TCP_KEEPALIVE 0x04
#endif

main(int argc, char ** argv)
{
int skeepalive = 60;
int gkeepalive;
int len = sizeof(gkeepalive);
int sock;
struct sockaddr_in server;
struct hostent *hp;
struct protoent *proto;

if (argc < 4) {
fprintf(stderr, “Usage: %s \n”, argv[0]);
exit(-1);
}

skeepalive = atoi(argv[3]);

if ((hp = gethostbyname(argv[1])) == 0) {
fprintf(stderr, “Wrong host!\n”);
exit(-1);
}
memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
server.sin_port = htons(atoi(argv[2]));
server.sin_family = AF_INET;

if ((proto = getprotobyname(“TCP”)) == NULL) {
perror (“getprotobyname”);
exit (-1);
}

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror(“socket”);
exit(-1);
}

if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &skeepalive, sizeof(int)) == -1) {
perror(“setsockopt(SO_KEEPALIVE)”);
exit(-1);
}

if (getsockopt(sock, proto->p_proto, TCP_KEEPALIVE, &gkeepalive, &len) == -1)
printf(“getsockopt() before connect failed. errno = %d\n”, errno);
else
printf(“getsockopt() before connect success. Idle time = %d\n”, gkeepalive);

if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
{
perror(“connect”);
exit(-1);
}

if (getsockopt(sock, proto->p_proto, TCP_KEEPALIVE, &gkeepalive, &len) == -1)
printf(“getsockopt() after connect is failed. errno = %d\n”, errno);
else
printf(“getsockopt() after connect is successed. Idle time = %d\n”, gkeepalive);

if (setsockopt(sock, proto->p_proto, TCP_KEEPALIVE, &skeepalive, len) == -1)
{
perror(“setsockopt()”);
exit(-1);
}

printf(“setsockopt is successed\n”);

if (getsockopt(sock, proto->p_proto, TCP_KEEPALIVE, &gkeepalive, &len) == -1)
{
perror(“getsockopt()”);
exit (-1);
}
printf(“getsockopt() now got idle time = %d\n”, gkeepalive);
printf("\nWaiting…, press a key to continue\n");

gkeepalive = getch();

close(sock);
}

Xiaodan Tang <xtang@qnx.com> wrote:

David F. Marker <> interprotech@ameritech.net> > wrote:
Have a TCP/IP server that manages up to 32 (1 listen + 31 potential
clients)descriptors underneath a QNX4 select Receive(). When the peer drops
their application the descriptor becomes ready and read for zero bytes–a
typical disconnection. However, if the peer does not properly shutdown the
socket (i.e. peer cold boot) I never get any notification that the they have
disconnected. Netstat show connection as still being established. I have
tried enabling SO_KEEPALIVE whereby keepalive probes are sent but I still am
not getting desired results. Any suggestions?

Are you sure the keepalive probe is send out? Be default, it will
only send out after 2 hours idle. You need TCP_KEEPALIVE to change
that 2 hours. Also, it take about 10min to probe and decided to
drop the link.

Sorry, forgot to mention that TCP_KEEPALIVE only works on latest
TCPIP 425 (that’s “C” ?) stack.

-xtang

Andrew Thomas <Andrew@cogent.ca> wrote:

Previously, David F. Marker wrote in qdn.public.qnx4:
Have a TCP/IP server that manages up to 32 (1 listen + 31 potential
clients)descriptors underneath a QNX4 select Receive(). When the peer drops
their application the descriptor becomes ready and read for zero bytes–a
typical disconnection. However, if the peer does not properly shutdown the
socket (i.e. peer cold boot) I never get any notification that the they have
disconnected. Netstat show connection as still being established. I have
tried enabling SO_KEEPALIVE whereby keepalive probes are sent but I still am
not getting desired results. Any suggestions?

David F. Marker
Interpro Technology, Inc.
interprotech@ameritech.net

TCP/IP timeouts are long, in the range of 5 to 15 minutes.

Hm… I had thought they were even longer than that… on the order
of hours? But I could be wrong.

This may sound like a pain, which it is, but that’s the world of
TCP/IP. It was never designed to be speedy in the face of abnormal
termination - it was meant to be robust in unreliable networks.

Yup. And robust on an unreliable network will give the exact opposite
in choice of behaviour from quickly detecting a failure.

-David

QNX Training Services
dagibbs@qnx.com

David Gibbs <dagibbs@qnx.com> wrote in message
news:95v0ga$s22$4@nntp.qnx.com

Andrew Thomas <> Andrew@cogent.ca> > wrote:
TCP/IP timeouts are long, in the range of 5 to 15 minutes.

Hm… I had thought they were even longer than that… on the order
of hours? But I could be wrong.

According to the docs (search in helpviewer): …at least every 2 hours…