[SOLVED] how do I detect a TCP connection disconnected from the other end
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
how do I detect a TCP connection disconnected from the other end
I have a thread in my process that acts as a simpe TCP server it should:
1) listen for an incoming tcp conection request,
2) then accept that connetion,
3) then wait for the disconnect from the other end.
The problem is in step 3) detecting the remote disconnection. I am using poll to wait for either of two events; another connection attempt or a disconnection.
My problem is that the poll() will return if another connection atempt is made, but will not return when the connection is dropped from the other end.
I could use keep-alive, but I want to know if it is possible to detect just the fact that the connection is closed remotely, without having to attempt to read or write to the TCP stream?
I could use keep-alive, but I want to know if it is possible to detect just the fact that the connection is closed remotely, without having to attempt to read or write to the TCP stream?
I would think that if the remote host closes the connection, it will just free up the resources (threads, memory, anything...) linked to the handle which is responsible for that particular connection and that it won't do anything fancy like sending you a specific message that signals to you that the connection is about to be or was closed (well, it probably depends on what kind of service is connecting to you - depending on how it is programmed).
I would think that if the remote host closes the connection, it will just free up the resources (threads, memory, anything...) linked to the handle which is responsible for that particular connection and that it won't do anything fancy like sending you a specific message that signals to you that the connection is about to be or was closed (well, it probably depends on what kind of service is connecting to you - depending on how it is programmed).
But it is always possible that they won't be able to for some reason, and the connection dies improperly. E.g., somebody hits the power switch, cable gets unplugged, OS kernel panic... So I think you have to keep alive if you want to be absolutely sure the connection hasn't died.
The usual way is to detect and EOF from the file descriptor used for I/O. You can also detect the close from a write that terminates early (return status... and test for EOF).
The usual way is to detect and EOF from the file descriptor used for I/O. You can also detect the close from a write that terminates early (return status... and test for EOF).
thanks, this was the information I needed, I was originally using select() with the TCP file descriptor addded to the exceptfds, but this did not work, so I tried poll().
But now I have found that when the TCP connection is closed from the remote end, it does flag 'read available', but the attempt to read returns 0 data bytes.
So now I am doing this:
Code:
...
fd_set read_fds;
fd_set error_fds;
FD_ZERO( &read_fds );
FD_ZERO( &error_fds );
FD_SET( fd_Listen, &read_fds );
FD_SET( fd_TcpStdio, &read_fds );
FD_SET( fd_TcpStdio, &error_fds );
int select_count = select( FD_SETSIZE, &read_fds, NULL, &error_fds, NULL );
if (select_count)
{
// fprintf(stderr, "select returned n = %i", select_count );
// if ( FD_ISSET(fd_Listen,&read_fds) ) fprintf(stderr,", fd_Listen is in read_fds");
// if ( FD_ISSET(fd_TcpStdio,&read_fds) ) fprintf(stderr,", fd_TcpStdio is read_fds");
// if ( FD_ISSET(fd_TcpStdio,&error_fds) ) fprintf(stderr,", fd_TcpStdio is in error_fds");
// fputc('\n', stderr);
if ( FD_ISSET(fd_Listen,&read_fds) )
{
puts_to_stderr("another TCP connection request received, so we close this one and allow the new connection to be accepted");
restore = TRUE;
}
else if ( FD_ISSET(fd_TcpStdio,&read_fds) )
{
int n;
puts_to_stderr("read available on fd_TcpStdio");
// char b;
// n = recv(fd_TcpStdio,&b,1,MSG_PEEK);
// fprintf(stderr,"recv returns n = %i\n", n);
// if ( n!=1 )
// {
// restore = TRUE;
// }
if ( ioctl(fd_TcpStdio,FIONREAD,&n) < 0 )
{
perror("ioctl error");
}
else
{
fprintf(stderr,"ioctl returns n = %i\n", n);
if ( n==0 )
{
restore = TRUE;
}
}
}
else if ( FD_ISSET(fd_TcpStdio,&error_fds) )
{
puts_to_stderr("error on fd_TcpStdio");
restore = TRUE;
}
...
setting the restore flag is what I do when I am ready to close fd_TcpStdio and listen / accept a new connection.
notice this code will not read from the fd_TcpStdio stream, if there is actual data coming in on this stream it is handled by a different thread, and this should not be considered a disconnection trigger.
The commented out recv with MSG_PEEK works just as well, but ioctl with FIONREAD seems more elegant (no need for 'char b', if there is real incoming data I don't need to see it).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.