How to notify an abnormal client termination to server?

764 views Asked by At

As the Title already says im looking for a way, to get notified when a client closes his Session unnormal.

I'm using the freeBSD OS. The server is running with Xamount threads (depending on CPUcore amount). So I'm not forking, and there isn't a own process for each client.

That's why sending an deathpackage all time_t seconds, to recive a SIGPIPE isn't an option for me. But i need to remove left clients from the kqueue, because otherwise after too many accept()'s my code will obviously run into memory troubles.

Is there a way, I can check without high performance loose per client, they are connected or not?

Or any event-notification, that would trigger if this happens? Or maybe is there a way of letting a programm send any signal to a port, even in abnormal termination case, before the Client process will exite?

2

There are 2 answers

0
Ingo Leonhardt On BEST ANSWER

According to the kqueue man page, kevent() should create an event when the socket has shutdown. From the description of th filter EVFILT_READ:

EVFILT_READ

Takes a descriptor as the identifier, and returns whenever there is data available to read. The behavior of the filter is slightly different depending on the descriptor type.

Sockets

Sockets which have previously been passed to listen() return when there is an incoming connection pending. data contains the size of the listen backlog.

Other socket descriptors return when there is data to be read, subject to the SO_RCVLOWAT value of the socket buffer. This may be overridden with a per-filter low water mark at the time the filter is added by setting the NOTE_LOWAT flag in fflags, and specifying the new low water mark in data. On return, data contains the number of bytes of protocol data available to read.

If the read direction of the socket has shutdown, then the filter also sets EV_EOF in flags, and returns the socket error (if any) in fflags. It is possible for EOF to be returned (indicating the connection is gone) while there is still data pending in the socket buffer.

5
Ingo Leonhardt On

Edit: that answer misses the question, because it's not about using kqueue. But if someone else finds the question by the title, it may be helpful anyway ...

I've often seen the following behaviour: if a client dies, and the server does a select() on the client's socket descriptor, select() returns with return code > 0 and FD_ISSET( fd ) will be true for that descriptor. But when you now try to read form the socket, read() (or recv()) return ERROR.

For a 'normal' connection using that to detect a client's death works fine for us, but there seems to be a different behaviour when the socket connection is tunneled but we haven't yet managed to figure that out completely.