EmbeddedRelated.com
Forums
Memfault Beyond the Launch

How to determine terminated TCP connection in Linux?

Started by Alexander Baranov September 24, 2004
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.


Alexander Baranov wrote:
> 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. > >
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.
On Fri, 24 Sep 2004 10:47:53 -0400, Alexander Baranov wrote:
> 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?
I'm using select & read for my tcp connections. Select waits for an event and I check it. If it's for one of my clients (one of many tcp sessions) I do a read. If the read returns < 0 and it's not a EWOULDBLOCK or read return 0 then I delete the client from my list of clients to check. Does this help? I think I read this in a Steven Book "Advanced Programming in the Unix Environment". I would suspect that the socket read function would return some error (and errno would be set). I hope that helps -- Linux Home Automation Neil Cherry ncherry@comcast.net http://home.comcast.net/~ncherry/ (Text only) http://hcs.sourceforge.net/ (HCS II) http://linuxha.blogspot.com/ My HA Blog
"Neil Cherry" <njc@wolfgang.uucp> wrote in message
news:slrncl8ik7.6av.njc@wolfgang.uucp...
> On Fri, 24 Sep 2004 10:47:53 -0400, Alexander Baranov wrote: > > 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? > > I'm using select & read for my tcp connections. Select waits for an > event and I check it. If it's for one of my clients (one of many tcp > sessions) I do a read. If the read returns < 0 and it's not a > EWOULDBLOCK or read return 0 then I delete the client from my list of > clients to check. Does this help? I think I read this in a Steven Book > "Advanced Programming in the Unix Environment". I would suspect that > the socket read function would return some error (and errno would be > set). I hope that helps > > -- > Linux Home Automation Neil Cherry ncherry@comcast.net > http://home.comcast.net/~ncherry/ (Text only) > http://hcs.sourceforge.net/ (HCS II) > http://linuxha.blogspot.com/ My HA Blog
Thank a lot. But I cannot understand two things. 1. The operator of TCP client console might leave console idle for hours. In this case recv() will return 0, but this situation is legal. 2. May I instead of using select() set my socket non-blocking? Thanks once more, Alex. The operator of TCP client console might be connected but might not press any key. He may leave console idle for any time before closing it In this situation The recv() will return 0 though the situation is quite legal. . Is it right or I am still missing something?
On 2004-09-24, Alexander Baranov <baranov@intech21.com> wrote:

>> I'm using select & read for my tcp connections. Select waits for an >> event and I check it. If it's for one of my clients (one of many tcp >> sessions) I do a read. If the read returns < 0 and it's not a >> EWOULDBLOCK or read return 0 then I delete the client from my list of >> clients to check.
> Thank a lot. But I cannot understand two things.
> 1. The operator of TCP client console might leave console idle > for hours. In this case recv() will return 0,
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 this situation is legal.
But it doesn't do what you think it does.
> 2. May I instead of using select() set my socket non-blocking?
If you want.
> The operator of TCP client console might be connected but > might not press any key. He may leave console idle for any > time before closing it In this situation The recv() will > return 0 though the situation is quite legal. . Is it right
You're wrong.
> or I am still missing something?
-- Grant Edwards grante Yow! Somewhere in Tenafly, at New Jersey, a chiropractor visi.com is viewing "Leave it to Beaver"!
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 <standard.disclaimer>
 _
Kevin D Quitt  USA 91387-4454         96.37% of all statistics are made up
  Per the FCA, this address may not be added to any commercial mail list
"Alexander Baranov" <baranov@intech21.com> wrote in message
news:aba0a$4154338c$44a55b44$16238@msgid.meganewsservers.com...
> 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.
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.
"FLY135" <fly_135(@ hot not not)notmail.com> wrote in message
news:7fZ4d.308$Ki1.240@newsread2.news.atl.earthlink.net...
> > "Alexander Baranov" <baranov@intech21.com> wrote in message > news:aba0a$4154338c$44a55b44$16238@msgid.meganewsservers.com... > > 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. > > 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. > >
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 :-).
Hi Alexander.

"Alexander Baranov" <baranov@intech21.com> wrote
> 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.
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: www.wanware.com
On 2004-09-24, Alexander Baranov <baranov@intech21.com> wrote:

> I read that keepalive really tests the integrity of Ethernet > connection.
Wrong. It's an end-to-end heartbeat done by the TCP stacks.
> and returns ENETRESET error if the connection is terminated > but I read that the timeout is 2 (in other articles - 4) > hours.
It varies a bit, but it's generally more than 1 and less than 10 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 > :-).
-- Grant Edwards grante Yow! It's today's SPECIAL! at visi.com

Memfault Beyond the Launch