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

Hi, I have a multithreaded socket client that i use to send and receive messages to/from a server.I would like my client to connect to the server if it can,if it can't it must try to connect every 500 ms(and loop until it connects). Once it is connected,it must make two threads of which each one calls a subroutine.All this is fine, My problem is that,if for some reason,the server disconnects,my client loops giving error messages.I want my client to detect that the server has disconnected,and retry to connect every 500ms. How can i detect that the socket went down,to pass my script back to step 1 where it tries to connect. Thanks for any help/suggestions. Here's my code
#!/usr/local/bin/perl use threads; use IO::Socket::INET; $error=1; my $MySocket; while (1) { if ($error eq 1) { if ($MySocket=new IO::Socket::INET->new(PeerPort=>1234 +,Proto=>'tcp',PeerAddr=>'192.168.100.9')) { $error=0; print "Connected $error \n"; } else { print "Could not connect try again 5ms \n"; select(undef, undef, undef, 0.5); $error=1; } } else { print "Hallo daar Error=$error\n"; $thread1 = threads->new(\&sendQMsg); $thread2 = threads->new(\&sendQMsg2); grep {$_->join;} ($thread1,$thread2); while ( my(@list)=threads->list()) { print "$#list\n"; grep { $_->join } @list; } } } sub sendQMsg { $message = "Hi from thread 1"; if ($MySocket->send($message)) { $error=0; } else { $error=1; } } sub sendQMsg2 { $message = "Hi from thread 2\n"; if ($MySocket->send($message)) { $error=0; } else { $error=1; } }
Before my MySocket->send i would like to see that the socket server went down,and this must pass control back to the place where i try to connect.Any suggestions? Thanks

Replies are listed 'Best First'.
Re: Check if Socket is alive before send
by shmem (Chancellor) on Nov 19, 2007 at 15:26 UTC
    The IO::Socket::INET manual page states
    DESCRIPTION
    "IO::Socket::INET" provides an object interface to creating and using sockets in the AF_INET domain. It is built upon the IO::Socket interface and inherits all the methods defined by IO::Socket.

    and IO::Socket provides the method connected():

    connected
    If the socket is in a connected state the peer address is returned. If the socket is not in a connected state then undef will be returned.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

      I'm not sure 'connected' does what you think it does. It tells you whether the remote-side address has been bound to the socket such that you can send via the socket without specifying a destination address. It is unclear to me whether some action on the remote side would cause connected() to stop returning the address that the socket was (and probably still is) bound to.

      The way I would tell that the socket needs to be reconnected would be to note that I got an error when I tried to send.

      - tye        

Re: Check if Socket is alive before send
by TOD (Friar) on Nov 20, 2007 at 05:00 UTC
    the reason why the server disconnects might be found in the 'Listen' parameter in the call to IO::Socket::INET->new. 'Listen' is somewhat mis-named, as it means the backlog argument in a call to the C-function listen(), see man 2 listen. you may get along with increasing the value to the highest possible one - which in fact depends on the system. in /usr/include/bits/socket.h (as on a debian box for instance) the constant SO_MAXCONN is defined. set the 'Listen' argument to the value defined there, and you will at least minimize the risk of "prematurely" rejected connections.
    --------------------------------
    masses are the opiate for religion.