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

i'm currently working on a daemonized process that collects UDP packets and processes them for database insertion. i'm running into an issue with blocking IO.

I've been using IO::Select and IO::Socket to create the needed sockets, and check if they're available for reading, but one of the collection sockets ( the UDP socket ) blocks if the UDP buffer has been emptied.

i've looked at the  select function, and ( after the annoying vector packing, etc ) it can be used to return the number of packets in the message buffer, so something like this can be achieved:

if ($nfound = select($rout = $rin, undef, undef, $time_left)) { for (1 .. $nfound) { $sock->recv($msg, $MAX_SIZE) or warn "Socket error!: $@\n"; }
so that once all the messages have been collected from the buffer, the program can move on and do other things.

my question: is there a similar method in IO::Select ( or IO::Socket )? i've read through the perldoc for both, and haven't seen one ( but i may be experiencing tunnel vision ).

the code i've been using ( that blocks ):

my $incoming = IO::Socket::INET->new( LocalPort => $MSGPORT, Proto => 'udp', Timeout => 1); ## some more code... while ( $incoming->recv( $msg, $MAX_SIZE ) ) { my ( $port, $addr ) = unpack_sockaddr_in( $incoming->peername +); push @messages, [ $addr, $msg ]; last if @messages > $MAX_INC_Q_SIZE; }

which works fine, until the message buffer only contains  $MAX_INC_Q_SIZE - 1 messages. then, the socket sits and waits for that one last message before exiting the collect loop and processing.

Replies are listed 'Best First'.
Re: IO::Select vs select function
by dws (Chancellor) on Aug 15, 2001 at 02:37 UTC
    For the path you're travelling, Lincoln Stein's Network Programming with Perl is a good companion. He goes into some detail about how to do non-blocking sockets with TCP, and may provide useful hints on how they can be done with UDP.

Re: IO::Select vs select function
by traveler (Parson) on Aug 15, 2001 at 00:35 UTC
    I'm using 5.6 and I cannot find the behavior you allude to for select. I believe it returns (and always has) the number of file descriptors available for I/O or with events select is set to detect. AFAIK, that is the only return value for select.

    ( the UDP socket ) blocks if the UDP buffer has been emptied

    I assume you mean that reading on the socket blocks if it is empty. You should be able to read the UDP socket to see if there is data on it. With fcntl's F_SETFL and O_NONBLOCK set, you should be able to read the socket until there is nothing to read. I have done this more than once on *nix systems with UDP sockets and IO::Select.

    HTH, --traveler