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

My program is receiving some message by using the recv function like below.
$MySocket->recv ($text,1000);
Actually what i want is if the recv function doesn't receive anything within 3secs then it will exit and i can print a "Time out message" in the console.

20061009 Janitored by Corion: Moved text out of code tags, as per Writeup Formatting Tips

Replies are listed 'Best First'.
Re: How time out can be done here?
by shmem (Chancellor) on Oct 09, 2006 at 11:55 UTC
    Read alarm. One way to do it:
    my $sec = 3; $SIG{ALRM} = sub { warn "Time out message: timed out after $sec seconds\n"; exit; }; alarm($sec); $MySocket->recv ($text,1000); alarm(0);

    Maybe you should localize the signal handler:

    { local $SIG{ALRM} = sub { ...}; alarm($sec); $MySocket->recv ($text,1000); alarm(0); }
    so that the alarm handler is visible only to the portion of code for which it is meant.

    --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}
Re: How time out can be done here?
by skx (Parson) on Oct 09, 2006 at 11:55 UTC

    You should look at using the "alarm" function to setup a timed alert - which can then be caught using eval.

    You don't give much sample code, but this might be a good starting point:

    # # Create a listening socket. # # # Never exit. # while (1) { # # Wait until we have an incoming connection # next unless $data = $main_socket->accept(); # # This eval block is here so that were can prevent DOS # attacks by closing sockets if there's nothing received. # after a while. # eval { # ten seconds. alarm( 10 ); # read data $data->recv ($text,1000); # cancel timeout alarm( 0); }; if ($@) { if ($@ =~ /timeout/) { # Timed out. Close socket. Exit. close($data); print "Timed out.\n"; } else { # normal exit close( $data ); } } }
    Steve
    --
Re: How time out can be done here?
by Anonymous Monk on Oct 09, 2006 at 12:14 UTC
    my $bits = ""; vec($bits,fileno(MySocket),1)=1; select($bits,undef,undef,3); if(vec($bits,fileno(MySocket),1)){ $MySocket->recv($text,1000) } else{ die("Time out!\n"); }
      Hi
      Thanks a lot for the code. But can you briefly explain me the code.
      Regd's
      Sanjay nayak.

        There's really nothing to explain. It does exactly what you asked for by calling select RBITS,WBITS,EBITS,TIMEOUT.

        Note that IO::Select is easier to use than select.

        use IO::Select (); my $sel = IO::Select->new($MySocket); my @read = $sel->can_read(3) or die("Time out!\n"); $MySocket->recv($text);
      Hi
      Thanks a lot.
      Regd's
      Sanjay Nayak