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

I write a client for (Web-)Servers over which I don't have command. The client should keep the Connection open, but Servers could time out and close the connection. The Client is a sub that holds the socket in a my variable. On every call the Client checks if the socket points to the Server and reopens it if not. That's the situation and now the question: Since I don't use select for my reads, how can I tell if the Server timed out? (I have used SuperSearch and found only a ref to a Node, wich talks about select-Servers)

Replies are listed 'Best First'.
Re: Losing Connection
by Abigail (Deacon) on Jun 26, 2001 at 22:50 UTC
    A closed socket will cause an eof to happen, right? If so, a read or a sysread will return 0.

    -- Abigail

      Sorry, an open socket which has currently no data (what happens if it has data I could not test) returns eof() too. I must know before I read because after open I must send data, and if the Server doesn't like me he could close the door into my nose. That eof I must distinguish from an eof because of the last Server timed out.
Re: Losing Connection
by MZSanford (Curate) on Jun 26, 2001 at 22:32 UTC

    Looking at the question, i would first think that the addition of select() is about the only way to get around this.

    But, in thinking, when writting to a closed socket, a PIPE signal will be generated. In the event of a PIPE signal, it can be checked by either installing a handler, or ignoring the signal. Such as :

    # method one $SIG{PIPE} = sub { $SERVER_DISCONNECT = 1; }; # # when printing to socket, check $SERVER_DISCONNECT # and handle if ($SERVER_DISCONNECT == 1) # method two (Posix systems only) $SIG{PIPE} = 'IGNORE'; use Errno ':POSIX'; # other code here unless (print SOCKET "$data") { if ($! == EPIPE) { # pipe error, attempt reconnection to server } else { # real error } }
    More Info :Network Programming with Perl (ISBN: 0-201-61571-1)
    and the she says, "well, this ones eating my popcorn"

    - Matt-Fu (MZSanford)

      Writing to a FIFO pipe that the last reader has closed will generate SIGPIPE but most (but not all) socket implementation will just have the write()/send() operation fail rather than generating the signal.

      If the server is using shutdown() to only close one side of the connection, then one has to use select to detect this without blocking.

              - tye (but my friends call me "Tye")
      That was my thougt too. Nope! If the Server(!) closes the socket, no Pipe-Signal is generated. I think it is because the Server could close only his end, and the writing channel stays open. But the Server could not answer on his already closed channel.