How to determine terminated TCP connection in Linux?

Hi, All. I am a new Linux programmer. I made a Linux TCP server for control applications. When some TCP client connects to it, goes into infinite console loop, getting characters, echoing them to client, parsing commands etc. Everything is OK until the client unexpectedly terminates the connection. I have to detect this event inside the loop and break. I thought that it might be done by analyzing socket state (i.e. if the state is not ESTABLISHED - break the loop) but from various examples and HOWTOs I did not see how to do it. It seems that I have to solve this problem in different way. Can anybody criticize and prompt? Regards, Alex.

Reply to
Alexander Baranov
Loading thread data ...

One thing to do - probably not the only thing:

If select returns positive and read returns 0, throw the connection away and try again.

I think the same applies if doing blocking reads - if read returns 0, throw the connection away.

Reply to
Bryan Hackney

No, it won't. If you're in non-blocking mode, it will return

-EWOULDBLOCK. If you're in blocking mode, it will block until some data has been sent by the client.

But it doesn't do what you think it does.

If you want.

You're wrong.

--
Grant Edwards                   grante             Yow!  Somewhere in Tenafly,
                                  at               New Jersey, a chiropractor
 Click to see the full signature
Reply to
Grant Edwards

Do yourself a favor: never write your own socket code. Make your employer buy _UNIX Network Programming_ by W. Richard Stevens, Volumes One and Two. Read the books when you can; use it as a cookbook in the meantime. Your computer will love you for it.

While you're at it, you should also consider getting _The Art of Computer Programming_ Volumes 1-3 by Donald E. Knuth. Understanding all of what's in these three books will make you a better programmer than 99.9% of those who are actually programmers.

--
#include 
 _
 Click to see the full signature
Reply to
Kevin D. Quitt

echoing

have

This question is of interest to me as well, and I can see that no one here has the answer. I haven't been doing much with Linux but there is a "keepalive" option implemented in some TCP stacks to make sure the connection is still active. You might want to research that.

An approach I am looking at using is to do a recv with timeout. If nothing comes and the recv times out then I will send data to the other connected socket. I am expecting that a blocking send will fail if the connected socket no longer exists. The problem is that while sitting in recv and the other end is idle that there is no way to differentiate between a dead or idle connection. Periodic sends of dummy data should reveal that the connected socket is dead if there is no ack on the sent data.

Reply to
FLY135

inside

nothing

the

Hi, FLY135, I read that keepalive really tests the integrity of Ethernet connection and returns ENETRESET error if the connection is terminated but I read that the timeout is 2 (in other articles - 4) hours. The point really is that the operator may be idle for hours and it is to be acceptable. Though, I haven't read Knuth yet :-).

Reply to
Alexander Baranov

Hi Alexander.

"Alexander Baranov" wrote

There are two ways that the server can see that the connection has gone away. First, a negative return on read() which is not EWOULDBLOCK. Second, include the socket in your list of error file descriptors which you pass to select(). If it indicates an error, the socket is likely gone (you might want to be more discriminating on errors; I'm not).

The other problem is that TCP may not notice that the socket has gone away for quite a long time. This is the case when you have nothing outstanding to be acked (by the client) when the session goes away and no attempt to send anything from the server until you get something from the client (which can no longer happen). This is what the TCP keepalives are for. They are on by default in most TCP implemenations but they tend to be in the 2 hour range. So a "poll" is only sent to the client every 2 hours and it isn't until then that you don't get a reponse and then get the session failing (and the read() failing or the exception indication). This is fine for things like telnet which are using a not very scarce resource (pseudo ttys). I set the timeout to about 2 minutes for connections:

on = 1; setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on)); value = 2 * 60; /* every 2 minutes */ setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, (char *)&value, sizeof(value));

Here on and value are ints.

As a side benefit if you are using a VPN, Cisco IOS times out idle sessions every hour. If you happening to be going through a Cisco and using VPN, the keepalives are considered traffic enough that Cisco doesn't see them as idle (defeating Cisco's idle feature, but of more use to my application).

Regards, Steve

------------------------------------------------------------------------ Steve Schefter phone: +1 705 725 9999 x26 The Software Group Limited fax: +1 705 725 9666

642 Welham Road, Barrie, Ontario CANADA L4N 9A1 Web:
formatting link
Reply to
Steve Schefter

Wrong.

It's an end-to-end heartbeat done by the TCP stacks.

It varies a bit, but it's generally more than 1 and less than

10 hours.

--
Grant Edwards                   grante             Yow!  It's today's SPECIAL!
                                  at               
 Click to see the full signature
Reply to
Grant Edwards

For that you'll need Stevens. 8o)

--
#include 
 _
 Click to see the full signature
Reply to
Kevin D. Quitt

echoing

inside

have

Second,

might

session

fine

Reply to
Alexander Baranov

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.