in reply to Re: Timeout Socket recv on UDP... on windows
in thread Timeout Socket recv on UDP... on windows

Thanks for the reply, all. I searched through the threads you referenced and saw good examples of setting non-blocking mode. I'm not sure I'm using this right, tho. If I place the statement after establishing the socket and before the while statement (while recv), the receive evaluates false and the while statement doesn't execute.

my $hSocket = IO::Socket::INET->new( LocalPort=>$intListenPort, Proto=>$strProtocol ) or die "Can't create UDP socket: $@"; ioctl($hSocket, 0x8004667e, pack("I", 1)); my ($datagram,$flags); # Wait for a datagram, then open a response port, respond, then close both ports. while ($hSocket->recv($datagram,42,$flags)) { ...
So, I'm wondering if this is the right approach. I think the core of the problem is that I'm waiting for incoming data to determine if a connection has been established.

Is there another way to watch for client connection (and corresponding technique to time-out), before establishing the recv loop? For instance, doesn't IO::Socket call an accept method on connection? So couldn't I check $hSocket for a value (undef?) until timeout, and then launch the recv loop once I have a client? Or maybe using the accept method directly, like

until ($hSocket->accept()) { ...check for timeout ...close socket and exit if timeout } while ($hSocket->recv($datagram,42,$flags)) { ...

I guess I'm asking if blocking is really the problem or my approach to checking for connection. I think...

Replies are listed 'Best First'.
Re^3: Timeout Socket recv on UDP... on windows
by BrowserUk (Patriarch) on Jan 26, 2008 at 16:31 UTC

    Caveat: I've had little occasion to do much with udp sockets. See also Perl Cookbook (I hope that is a sanctioned link)

    However, udp is connectionless, so you do not need an accept loop. Essentially you want to wait for upto a specified number of seconds for a datagram to arrive and do something else if not. So,

    my $hSocket = IO::Socket::INET->new( LocalPort=>$intListenPort, Proto=>$strProtocol ) or die "Can't create UDP socket: $@"; ioctl($hSocket, 0x8004667e, pack("I", 1)); my( $gotone, $datagram, $flags) = 0; my $endtime = time() + $timeout; while( time() < $endtime ) { sleep 1 and next unless $hSocket->recv($datagram,42,$flags ); ## Got a datagram. ... $gotone = 1; last; } if( $gotone ) { ## We processed a datagram within the timelimit } else { ## we didn't }

    There are probably better ways of structuring that. And you could probably use select or IO::Select to achieve a similar thing.

    Or threads.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.