As suggested above, for sockets you can set the handle (temporarily if preferred) to non-blocking and then use sysread to perform unbuffered IO:
#! perl -slw use strict; use IO::Socket; my $buffer = ''; sub timedReadline { my( $handle, $timeout ) = @_; my $state = 1; ioctl( $handle, 0x8004667e, \$state ); my $end = time() + $timeout; while( time() < $end and $buffer !~ m[\n] ) { my $read = sysread( $handle, $buffer, 100, length( $buffer ) ) +; sleep 1; } $state = 0; ioctl( $handle, 0x8004667e, \$state ); my $n = 1+index $buffer, "\n"; return unless $n; return substr $buffer, 0, $n, ''; } my $server = shift; my $fh = IO::Socket::INET->new($server); my $line = timedReadline( $fh, 5 ); die "***timeout***" unless $line; print "Got: $line"; print scalar <$fh>; ### Normal blocking read __END__ C:\test>junk7 localhost:54321 Got: You're connected Goodbye C:\test>junk7 localhost:54321 ***timeout*** at C:\test\junk7.pl line 26.
If you dump the idea of POSIX-compatibility (which on Win32 is tenuous at best, and frustratingly limited otherwise), then the OS provides many mechanisms for achieving timed reads and writes.
Perhaps the simplest is using SetCommTimeouts() which ought to be usable on any type of handle--terminals, files, sockets etc.--and should be usable via Win32::API and realisable as a module that exports a simple function (saysetTimeout( $fh )), but my quick attempt using Win32API::File::GetOsFHandle() to obtain the native filehandle underlying the Perl equivalent has so far been unsuccessful. But then, I've been unsuccessful in using GetOsFHandle() for other purposes in the past.
If I find the time this week, I'll try to knock up an XS or Inline::C version and see how I get on with that.
In reply to Re: Timeouts: Any alternative to alarm in Win32?
by BrowserUk
in thread Timeouts: Any alternative to alarm in Win32?
by jbbarnes
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |