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

(Running AS 5.8.6 on WinXP)

I'm trying to set a socket to nonblocking mode:

use IO::Socket::INET; my $sock = IO::Socket::INET->new( PeerAddr => 'peer', PeerPort => 9876, Proto => 'tcp', Type => SOCK_STREAM, Blocking => 0 ) || die $!; $sock->close();
It always dies (tho the error seems to flip around between
Bad file descriptor at iosock.pl line 3.
and
IO::Socket::INET: ...propagated at iosock.pl line 3.
After stepping into IO::Socket::INET, the failure is always on the $sock->blocking() call.

I found node Re: Net::SSH::Perl error message, which points to an old activestate bug report that essentially says I'm SOL.

  1. Does this Win32 nonblocking sockets issue still exist ?
  2. If so, is there a known workaround for trying to send() large buffers wo/ blocking for an extended period ? Is there a way to safely shut off the offending SO_SYNCHRONOUS_NONALERT socket option after connecting, and then setting $sock->blocking(0) ?

Update:

Once again, I posted too soon. After changing my supersearch terms, I found Re^2: nbtstat.pl fails for non-windows IP, which provides a number of pointers, esp the ioctl(). Hopefully it will work as advertised...

Replies are listed 'Best First'.
Re: Nonblocking sockets on Win32
by ikegami (Patriarch) on Nov 28, 2005 at 22:38 UTC

    It's a known bug.

    This *seems* to work. (The side-effects are unknown to me.)

    sub POSIX_FIONBIO () { (0x80000000 | (4<<16) | (ord('f')<<8) | 126) } + # 0x8004667E ioctl($sock, POSIX_FIONBIO, pack("I", 1)) or $! == 0 # ** or die(...); # ** - ioctl is returning undef, # yet both $! and $^E are 0. # I don't know what this means.
      Ahh, thnx, that did it...with one tiny change: I had to explicitly clear $! before the call; apparently, ioctl() isn't clearing it on its own.

      I had tried a similar recommendation which said the param value had to be a ref:

      $nonblock = 1; ioctl($sock, POSIX_FIONBIO, \$nonblock); # !!WRONG
      but that would only set nonblock, but couldn't set back to blocking.

      And an FYI: this worked with a IO::Socket::INET handle.

        This node is also particular informative - Re: (to be updated) (tye)Re: Non blocking socket open - I used some of the code therein to build a cross-platform, non-blocking network event engine which has proven to be particularly robust since deployment.

         

        perl -le "print unpack'N', pack'B32', '00000000000000000000001000000000'"