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

I have a program that reads from a socket I created with IO::Socket::INET. Most of the time, I want the calls to sysread and $sock->accept() to block. But just one time I need to check if I've received anything over the socket. If there is nothing there, I don't want it to block forever, I want it to move on. In Windows, I think the only way to get a non-blocking socket is to use the ioctl function like:
my $true = 1; ioctl($sock,0x8004667e,\$true);
I found this lovely gem on this site and it's worked well. My first thought to solve my problem was to make my socket non-blocking with ioctl, read from it, then change it back to blocking with a similar ioctl call. Unfortunately, this doesn't work. I tried setting $true to 0, -1, and undef and all have the same effect, they make the socket non-blocking. So my question is this: Is there any way to reverse the non-blockingness caused by an ioctl call? I have tried other methods (like an alarm), but these don't work in Windows. When perl is blocked in a sysread, I can't get it to catch sig int or sig alrm. Please help!

Replies are listed 'Best First'.
Re: ioctl for non-blocking and blocking in Windows
by bart (Canon) on Apr 16, 2007 at 11:11 UTC
    salva claims in Re: Non-blocking socket read on Windows that
    ioctl($socket, 0x8004667e, $nonblocking); $nonblocking = 1 => makes the socket non blocking,
    $nonblocking = 0 => makes the socket blocking.
    So he's not using a scalar reference...

    I also found use of the magic number in a CPAN module, Win32::Socketpair, again, by salva. Again, not using a reference.

    p.s. in my internet search I stumbled across a rather interesting recent blog post.

      my $nonblocking = 1; ioctl($sock, 0x8004667e, $nonblocking) or die "ioctl socket: $!\n"; my $sockread = sysread($sock, $buffer, $chunk); #should be non-blockin +g $nonblocking = 0; ioctl($sock, 0x8004667e, $nonblocking) or die "ioctl socket: $!\n"; $sockread = sysread($sock, $buffer, $chunk); #should block
      The code above produces the helpful error message: "ioctl socket: Unknown error." I got rid of the die part and the socket was still blocking on the first read. If I replace $nonblocking with \$nonblocking, both reads are non-blocking. I, too, stumbled across that blog post and it seems to agree that you must pass ioctl a reference as the last argument.
Re: ioctl for non-blocking and blocking in Windows
by Anonymous Monk on Apr 16, 2007 at 17:54 UTC
    I had so many Firefox tabs on this subject open, that I missed the one that had the solution. Link
    ioctl($sock, 0x8004667e, pack("I", 1)); # Sets non-blocking ioctl($sock, 0x8004667e, pack("I", 0)); # Sets blocking