Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

syswrite and closed sockets

by InfiniteLoop (Hermit)
on Aug 11, 2006 at 14:52 UTC ( [id://566852] : perlquestion . print w/replies, xml ) Need Help??

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

Greetings Monks,
 Im using IO::Socket::INET to communicate with a messaging server. The code somewhat looks like this:
$socket = IO::Socket::INET->new( PeerAddr=> $self->host, PeerPort=> $self->port, Proto=> "tcp", Blocking => 1 ); .... $socket->syswrite($string, length($string));

 Im implementing a failover mechanism, where if the syswrite fails, I would then connect to another set of host and retry the syswrite.

 If the server shutsdown or is not accesssible, the syswrite does not report any errors. I have read the perldoc's and searched this venerable monastry, but did not find any clues. Any help is appreciated. Thanks.

Update: According to the docs, syswrite returns undef if there was an error. I modified the syswrite to look like this:
if(!($socket->syswrite($string, length($string)))){ print "Error writing\n"; }
just before the syswrite, I shutdown the server to which the socket was connected and attempted to write to the socket, it did not report any error

Replies are listed 'Best First'.
Re: syswrite and closed sockets
by Thelonius (Priest) on Aug 11, 2006 at 16:26 UTC
    Did the syswrite return a true value or did you just not wait long enough for it to return at all?

    When you say you shut down the server, do you mean the server processs or the whole computer? If you shut down the whole computer, the time-out can take a long time--the default on Linux is somewhere between 13 and 30 minutes! (And that's assuming the two processes are on different computers. If they're on the same computer, you'll wait even longer for a reply if you shut it off :-)

    On the other hand, if you just shut down the process, you should get an error "immediately".

    P.S. $socket->syswrite($string, length($string)) can be shortened to $socket->syswrite($string). I seem to vaguely recall that that may not always have been the case.

      Actually I shutdown the server process, to which my socket was connected. Even so, the syswrite returned true, i.e the write succeeded.

      Here is the background: my test script opens a socket to the server and sleeps for 10 seconds, followed by a syswrite on the socket. During this 10 second window, I shutdown the server process (which takes around 3 seconds). I noticed even when the server process is not there anymore, the syswrite succeeds.

        Have the server use shutdown to make the closing of the connection be more explicit to the clients.

        I consider it a bug or design flaw that some TCP network stacks don't appear to do the equivalent of shutdown when a socket is closed, which means that the client won't know about the closure until it tries to send more data and waits a short while for the reply to that data to show up and tell it that the connection is no longer valid.


        See also (tye)Re: shutdown vs. close on INET sockets.

        If you don't have control over the server, then you can change your test to have the client:

        1. Open the socket to the server
        2. Wait 10 seconds while you stop the service
        3. Write to the socket hoping for failure
        4. If no failure, wait 10 more seconds
        5. Write to the socket again

        It shouldn't take very long for the response to a write to a closed socket to make it back to the client. However, if you shut off the server computer or break the network connection to it, then it may take 8 minutes before the client is willing to give up on the server.

        - tye