Testing on my system, I'm not sure the Timeout is working properly for connects.
Try this version with explicit timeouts for attempts over $timeout seconds.
Also, notice the extreme difference in 'user' and 'sys' times :)
#!/usr/bin/perl
# http://perlmonks.org/?node_id=1135109
# http://perlmonks.org/?node_id=11103970
use strict;
use warnings;
use IO::Socket;
use IO::Select;
use Time::HiRes qw( time );
my @ips = map "192.168.1.$_", 1..20; # your IPs here
my $port = 22; # your port here
my $max = 1000; # somewhat smaller than max "open files"
my $timeout = 1;
my %handles;
my $sel = IO::Select->new;
while( @ips or $sel->count )
{
if( @ips and $sel->count < $max )
{
my $ip = shift @ips;
my $fh = IO::Socket::INET->new(PeerHost => $ip, PeerPort => $port,
Proto => 'tcp', Blocking => 0);
$handles{$fh} = ["$ip:$port", $fh, time];
$sel->add($fh);
}
elsif( @ips ? $sel->count >= $max : $sel->count )
{
my @connects;
for my $fh ( @connects = $sel->can_write($timeout) )
{
print $fh->connected ? ' ' : 'not', " alive $handles{$fh}[0]\
+n";
$sel->remove($fh);
delete $handles{$fh};
}
if( not @connects )
{
my $time = time - $timeout;
for my $key ( keys %handles )
{
if( $handles{$key}[2] < $time )
{
print "not alive $handles{$key}[0]\n";
$sel->remove( $handles{$key}[1] );
delete $handles{$key};
}
}
}
}
}
There are several different ways to do the timeouts, I'm curious how this one works out.
Others may be slightly faster on wall clock, but use much more CPU.
|