Abroxa has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

Currently I am creating a client/server application. Whenever the client wants to finish his session, he has to logout by telling the server that in a special way. There could be some exceptions where the client does not logout correctly: i.e. The connection was forced to be cut by the provider for example, or the client just closed the connection without logging out correctly. My problem at this time: Is there a way to let the server know when a client does not logout correctly? Up to now I tried the following:
$client->close() unless (defined($client->peerhost())); # I am working with IO::Socket::INET Objects.
On my Debian 3.0 / Perl 5.6.1 machine this works fine ( I didn't think about performance up to now. )
I was very surprised to see that this doesn't work at all on Win32 systems and I want my application to be compatible with many operating systems.

Is there a better way to detect whether a client has cut off the connection?

Thanks in advance, Abroxa

Replies are listed 'Best First'.
Re: Detecting disconnection from client using IO::Socket Objects.
by edan (Curate) on Sep 17, 2003 at 16:24 UTC

    Without really knowing how you have implemented your server, I can give you the following advice if you are doing non-blocking I/O with the help of IO::Select or IO::Poll:

    After getting a read-event on the socket, you'll go to do your sysread, and you'll get back 0 bytes. That means the client closed the socket. The following code snippet illustrates:

    my $bytes_read = $socket->sysread($buf, $max_read_len); if (not defined $bytes_read) { print "ack! error on the socket\n"; } elsif ($bytes_read == 0) { print "the socket was closed\n"; } else { print "woo hoo! I read $bytes_read bytes from the socket...\n"; }

    You might want to look at this node for more info:
    Detecting a closed socket

    HTH

    --
    3dan

      At first many thanks to sgifford and 3dan

      And yes, I do use IO::Select with Nonblocking Handles and am waiting for can_read() has something for me.
      Do I see that right that in my - lets call it "check_connected" - routine, I have to call sysread on the socket, and my connection status depends on its ( sysread's ) return values? Seems to make sense to me.

      -trial 'n error with many thanks :)-
      Abroxa
Re: Detecting disconnection from client using IO::Socket Objects.
by sgifford (Prior) on Sep 17, 2003 at 16:06 UTC

    TCP by default doesn't provide a mechanism for checking whether a system has gone away. The only way to know is if you try to send data to the system and you never get an acknowledgement.

    The traditional way to fix this is using timeouts and/or some kind of NOOP command that either side can send to probe if the other side is down without affecting the state of the connection.

    You could also try the SO_KEEPALIVE socket option, which trys to automate this at the TCP level. It's not very flexible, though, and has very long timeouts.