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

Hi,

I am running ActiveState Perl 5.8.8 on Windows XP, SP3.

I am trying to find a way to timeout an IO::Socket::INET request, but am having difficulty.

The problem is that the Timeout parameter is not implemented for some reason (though it does exist), and on Windows it seems that alarms don't work either.

I've tried various things, but all to no avail. The code I'm testing looks much like this:

#!d:/perl/bin/perl.exe use warnings; use strict; use IO::Socket; $SIG{ALRM} = sub { die "timeout" }; eval { alarm(3); my $socket=new IO::Socket::INET( PeerAddr=> 'www.somedomain.com', PeerPort=> 80, Proto => 'tcp', Timeout => '3') || die "Could not Connect $!\n"; print $socket "GET / HTTP/1.0\n\n"; while(<$socket>) { # .... } alarm(0); };

All I'm really doing is needing to get headers back from a number of sites, but some of the domains will be dead (and don't timeout for ages), or may take a while longer than the couple of seconds which I want to allow. However, although I know that I could use alarms and signals etc on Linux, it seems very difficult to find any solution - elegant or not - for Windows.

I've searched high and low for a solution, and found similar queries going back years, but as yet cannot find any way around the problem, yet I cannot believe that there isn't a way to do this.

Any assistance appreciated!

Replies are listed 'Best First'.
Re: use IO::Socket / Windows Timeout
by zentara (Cardinal) on Aug 06, 2010 at 20:02 UTC
    Try Timeout Socket recv on UDP... on windows and Timeouts: Any alternative to alarm in Win32?. Also, a good way to implement your own timeouts, is to put your code into a thread, and have the main thread act as a timer on the child threads.That is what I would do. See Re^3: sleep and timing? or here is a rudimentary example that works on linux. Or wait for BrowserUk to give some win32 thread code.
    #!/usr/bin/perl -w use strict; use threads; use threads::shared; my $timer_go:shared = 0; my $worker = threads->create(\&worker); my $timer = threads->create(\&timer,$worker); print "hit enter to start\n"; <>; $timer_go=1; <>; $timer->join(); $worker->join(); sub timer { my $worker = shift; while(1){ if($timer_go){ my $count = 0; while(1){ $count++; if($count > 5){ print "timed out\nHit enter to finish\n"; # Send a signal to a thread $worker->kill('INT'); return; } sleep 1; print "timing $count\n"; } }else{sleep 1} } } sub worker { $|++; $SIG{INT} = sub{ warn "Caught Zap!\n"; sleep 1; exit; }; my $worker_pid = open( READ, "top -d 1 -b |" ); print "\t$worker_pid\n"; return; }

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku
Re: use IO::Socket / Windows Timeout
by BrowserUk (Patriarch) on Aug 06, 2010 at 21:13 UTC

    Do you have a url for a particularly slow website?

    I think I have a good solution for you, but it's difficult to test as these days DNS servers tend to respond to unknown addresses with a page of f'ing adverts.

    My usual "slow" test is Perlmonks, but it's running surprisingly quickly today.


    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.

      My problem is not with Web sites, but with laboratory instruments that "report" either via built-in HTTP server or via direct TCP connection. Both tend to occasionally "freeze", after the connection has been successfully established. Strangely enough, timeout at socket creation seems to work.

      I would appreciate if you would share the "good solution" you mentioned. It has been almost 15 years, but I suspect it will still be good :-D

      Thanks!

        The user in question sadly has not been active here for years. A better approach would be to start a thread for your actual problem, rather than something which doesn't fit in with the existing thread. How do I post a question effectively?.

      Thanks for both the comments ... Haven't yet had a chance to look at the first response properly though, but looks interesting, and will post back how that works out.

      Meantime, yes, a particularly slow response can be got from the following domain: http://www.lxdirect.com

      It used to be an active retail site, but they've now re-branded, etc. However, you'll wait up to 30 seconds or so for a response, at which point it fails (try it in a browser first if you like). It was only by chance that I realized that it was causing such a delay, but then figured I would need to handle such instances anyway ...

      Thanks again, and any help appreciated.