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

Is it possible to have IO::Socket time out a connection if it can't connect within a second, or some defined amount of time? I think there was some timeout flag in the POD, but it didn't do anything. I'm on Win32 so I can't fork or do the alarm technique.

Thanks

Replies are listed 'Best First'.
(tye)Re: IO::Socket Timeout?
by tye (Sage) on Dec 23, 2000 at 01:07 UTC

    IO::Socket uses alarm() to time-out a connect(). But Win32 doesn't have alarm() so under Win32 IO::Socket just silently doesn't do the alarm() and the connect() will hang as long as it wants to.

    Of course, you could use async sockets to do an async connect() and even patch IO::Socket to support this since it is perhaps more portable than alarm(). Unfortunately that won't help you since every version of WinSock I've found has a bug where connect() on an async socket doesn't work. Win32 does support async TCP/IP connects but you have to use the proprietary APIs to avoid the bug.

    Anyway, I thought some more details might be interesting.

    Sorry, I don't have details on Win32::Internet and if that allow async connections. If it does, perhaps IO::Socket should be patched to use that if it is available and time-outs are requested.

            - tye (but my friends call me "Tye")
Re: IO::Socket Timeout?
by c-era (Curate) on Dec 22, 2000 at 20:52 UTC
    To put is shortly, not with active state perl. You can take a look at Win32::Internet, it offers some functionality.

    If you are running this on just your computer then you can install cygwin (provides posix compliance to windows) and cygwin perl, then everything will work as it would on unix.

Re: IO::Socket Timeout?
by Fastolfe (Vicar) on Dec 22, 2000 at 20:08 UTC
    This works for me:
    $S = IO::Socket::INET->new( PeerAddr => "some.unreachable.ip:80", Proto => "tcp", Timeout => 1) or die "Couldn't connect: " . ($! ? $! : $@); # this too: $S = IO::Socket::INET->new(Proto=>"tcp", Timeout=>1); $sin = sockaddr_in(80, inet_aton("some.unreachable.ip")); $S->connect($sin) or die "Couldn't connect: " . ($! ? $! : $@);
    Both of these time out, obeying the value I placed in the Timeout field. If you're having difficulty getting this to work, perhaps Win32 doesn't work well with these timeout settings? See also the 'timeout' method in IO::Socket. I would figure that setting the Timeout argument in the constructor would set this, but *shrug*.

    You may just be SOL on the Win32 platform... An alternative might be to use something like Net::Ping to verify the host is reachable before trying to connect to it. The only way your connection should time out at that point is if the port is being filtered by firewalling software that doesn't send ICMP errors.