Socket disconnect detect
POLLRDHUP (since Linux 2.6.17)
Stream socket peer closed connection, or shut down writing half of connection. The _GNU_SOURCE feature test macro must be defined (before including any header files) in order to obtain this definition.
This socket was connected but the connection is now broken. In this case, send generates a SIGPIPE signal first; if that signal is ignored or blocked, or if its handler returns, then send fails with EPIPE.
tcp_disconnect.py This program easily translates to C & Java. By TCP rules, the only way for a server program to know if a client has disconnected, is to try to read from the socket. Specifically, if select() says there is data, but recv() returns 0 bytes of data, then this implies the client has disconnected. But a server program might want to confirm that a tcp client is still connected without reading data. For example, before it performs some task or sends data to the client. This program will demonstrate how to detect a TCP client disconnect without reading data. The method to do this: 1) select on socket as poll (no wait) 2) if no recv data waiting, then client still connected 3) if recv data waiting, the read one char using PEEK flag 4) if PEEK data len=0, then client has disconnected, otherwise its connected. Note, the peek flag will read data without removing it from tcp queue. To see it in action: 0) run this program on one computer 1) from another computer, connect via telnet port 12345, 2) type a line of data 3) wait to see it echo, 4) type another line, 5) disconnect quickly, 6) watch the program will detect the disconnect and exit. I hope this is helpful to someone. John Masinter, 17-Dec-2008. """
Returns the amount of queued unread data in the receive
buffer. Argument is a pointer to an integer. The socket
must not be in LISTEN state, otherwise an error (EINVAL)
Returns true when the all urgent data has been already
received by the user program. This is used together with
Argument is an pointer to an integer for the test result.
Returns the amount of unsent data in the socket send queue
in the passed integer value pointer. The socket must not
be in LISTEN state, otherwise an error (EINVAL)
Linux provides a SIOCOUTQ ioctl() to query how much data is in the TCP output buffer:
You can use that, plus the value of SO_SNDBUF, to determine whether the outgoing buffer has enough space for any particular message. So strictly speaking, the answer to your question is "yes".
But there are two problems with this approach. First, it is Linux-specific. Second, what are you planning to do when there is not enough space to send your whole message? Loop and call select again? But that will just tell you the socket is ready for writing again, causing you to busy-loop.
For efficiency's sake, you should probably bite the bullet and just deal with partial writes; let the network stack worry about breaking your stream up into packets for optimal throughput.
SO_SNDBUF FIONREAD MSG_PEEK
man 7 socket
You can change the size of the receive and the send buffer as follows (send buffer shown):
int buffersize = 64*1024; // 64k
setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *) &buffersize, sizeof(buffersize));
and to get the current size, use:
getsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char &) &buffersize, sizeof(buffersize));
ret1 = recv(fd, buffer, 32, MSG_PEEK | MSG_DONTWAIT);
This flag causes the receive operation to return data from the beginning of the receive queue without removing that data
from the queue. Thus, a subsequent receive call will return the same data.