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

I am using some code I found off the internet to monitor a game server. Unfortunately after a certain amount of time the script always gets stuck at one spot. This is the code:
my $Socket = new IO::Socket::INET ( Proto => "udp", PeerAddr => $Settings{ServerIP}, PeerPort => $Settings{ServerPort}, ); if ($Socket) { open (ERROR, ">/dev/null") or die $!; STDERR->fdopen(\*ERROR, "w") or die $!; $Socket->send($Settings{RCONCommand}) or next; $SIG{ALRM} = \&Timeout; print"."; eval { alarm (4); $Socket->recv($Info{Data},16384) or next; alarm (0); close $Socket; } } else { close $Socket; }
It always gets stuck at this line: "$Socket->recv($Info{Data},16384) or next;" which happens when nothing is received back from the server. What do I have to do exactly to get it to time out? I have been working at this for the last 12 hours and it's beyond my ability to get it working. I will use any hack of a solution anyone can come up with, I am really desparate to get this working.

Replies are listed 'Best First'.
Re: IO::Socket::INET $Socket->recv won't time out
by targetsmart (Curate) on Mar 13, 2009 at 07:01 UTC
    The recv() call is normally used only on a connected socket

    from recv manual page in unix system( basically recv system call)
    but perldoc -f recv says, (perl's recv function)
    This call is actually implemented in terms of recvfrom(2) system call. See "UDP: Message Passing" in perlipc for examples.
    so you can see man perlipc
    I think in this case that server has nothing to give you immediately, you can use MSG_DONTWAIT flag in recv, (on unix systems see man recv for more information on flags to recv). this will make recv to return immediately if no data is available on socket.
    Alternatively you can use select function to wait for data to be ready on the socket , if it is ready go and read it using recv. See perldoc -f select or man perlipc


    Vivek
    -- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.
      The recv() call is normally used only on a connected socket

      That's actually a connected socket, new() connects socket if PeerAddr and PeerPort specified.

Re: IO::Socket::INET $Socket->recv won't time out
by zwon (Abbot) on Mar 13, 2009 at 19:19 UTC

    You should use IO::Select or select.

    @ready = IO::Select->new($Socket)->can_read(4); if (@ready) { $Socket->recv($Info{Data},16384); }