> I'm writing a threaded server app, and I want to find a good way of
> checking if there's a lost connection. There are two threads set up for
> each client (read and write), and one feof check in each of them
> to see if the client is still connected.
If you just want to handle normal disconnects (e.g. other side goes away
normally), use select(). When the socket handle in the readfds
collection gets set, you'll call recv(), which will return 0 to indicate
that the connection has been dropped.
If you want to handle abnormal disconnects (cable unplugged, remote peer
crashed, etc.) you need to have some kind of fairly regular
communication going on. Then each side keeps track of the last time it
heard anything from the remote side: if it's been too long (say, 60
seconds), you can assume that the remote peer isn't there any more.
Avoid the temptation to do the latter. For one thing, it leads to
"noisy" protocols -- they use more bandwidth than quiet ones for the
same amount of real functionality. For another, a cable getting
unplugged isn't always an error: what if the user moves his Ethernet
cable from one port on the hub to another just at the point where your
timeout routine is about to go off? You'd drop the connection, even
though the situation was temporary, and no one would have lost data.
Quote:> But when I tried this out, I got
> a broken pipe error. It seemed like the fputs call in the write thread
> was being called before the feof check was reached, so I tried placing an
> feof right before the fputs...still got the pipe error. The current
> "solution" is signal(SIGPIPE, SIG_IGN)...but this makes me feel real
> bad (perhaps it shouldn't? is there something wrong/hazardous with
> ignoring SIGPIPE??).
I don't know why you're getting SIGPIPE: it's usually sent when someone
pipes input into your program, and then the data source goes away.
SIGPIPE kills the recieving program because that's the right thing to
do: no more data coming in, so the "server" isn't needed any more. An
$ ls |cpio -ocvB > foo.cpio
This would archive all files in the current directory to a cpio file
called foo. When ls finishes writing out the directory list, cpio gets
sent SIGPIPE, so it knows there's no more file names coming in on stdin.
Your SIGPIPE must be because you're misusing feof() and such. It's okay
to ignore SIGPIPE when you know what you're doing, but in this case, you
shouldn't be getting it at all. Just use select() -- it's much better
for your purpose.
= Warren Young, maintainer of the Winsock Programmer's FAQ at:
= ICBM Address: 36.8274040 N, 108.0204086 W, alt. 1714m