2010-08-25 64 views

回答

17

如果您检查您会看到代码(我从我的Ubuntu 10.04复制它):

 my $timeout = ${*$sock}{'io_socket_timeout'}; 
#  my $before = time() if $timeout; 

     undef [email protected]; 
     if ($sock->connect(pack_sockaddr_in($rport, $raddr))) { 
#   ${*$sock}{'io_socket_timeout'} = $timeout; 
      return $sock; 
     } 

     return _error($sock, $!, [email protected] || "Timeout") 
      unless @raddr; 

#  if ($timeout) { 
#   my $new_timeout = $timeout - (time() - $before); 
#   return _error($sock, 
#       (exists(&Errno::ETIMEDOUT) ? Errno::ETIMEDOUT() : $EINVAL), 
#       "Timeout") if $new_timeout <= 0; 
#   ${*$sock}{'io_socket_timeout'} = $new_timeout; 
#  } 

显然超时的东西被注释掉,这样expleins为什么它被忽略。

我发现一个post约会从2003年,这是讨论。 (底部)一个建议是在得到由报警信号终止的eval块打开插座:

eval { 
    local $SIG{ALRM} = sub { die 'Timed Out'; }; 
    alarm 3; 
    my $sock = IO::Socket::INET->new( 
    PeerAddr => inet_ntoa(gethostbyname($host)), 
    PeerPort => 'whois', 
    Proto => 'tcp', 
    ## timeout => , 
); 
    $sock->autoflush; 
    print $sock "$qry\015\012"; 
    undef $/; $data = <$sock>; $/ = "\n"; 
    alarm 0; 
}; 
alarm 0; # race condition protection 
return "Error: timeout." if ([email protected] && [email protected] =~ /Timed Out/); 
return "Error: Eval corrupted: [email protected]" if [email protected]; 

不是很优雅,但如果它工作...

让我们验证与缓慢的服务器和客户端不耐烦:

# Impatient Client 
use IO::Socket::INET; 

$sock = new IO::Socket::INET(
    PeerAddr => "localhost", 
    PeerPort => "10007", 
    Proto => 'tcp', 
    Timeout => 2, 
    ); 

print <$sock>; 

close($sock); 


# SlowServer 
use IO::Socket::INET; 

$sock = new IO::Socket::INET(
    LocalAddr => "localhost", 
    LocalPort => "10007", 
    Proto => 'tcp', 
    Listen => 1, 
    Reuse => 1, 
    ); 

$newsock = $sock->accept(); 
sleep 5; 

#while (<$newsock>) { 
# print $_; 
#} 
print $newsock "Some Stuff"; 
close($newsock); 
close($sock); 

,如果我们运行这个命令:

[email protected]:~/playpen$ perl server.pl& 
[1] 9130 
[email protected]:~/playpen$ time perl test.pl 
Some Stuff[1]+ Done     perl server.pl 

real 0m5.039s 
user 0m0.050s 
sys  0m0.030s 

所以igno重新设置2秒的超时时间并运行5秒钟。

现在对方不耐烦客户端:

use IO::Socket::INET; 
eval { 
    local $SIG{ALRM} = sub { die 'Timed Out'; }; 
    alarm 2; 
    $sock = new IO::Socket::INET(
    PeerAddr => "localhost", 
    PeerPort => "10007", 
    Proto => 'tcp', 
    Timeout => 2, 
    ); 

    print <$sock>; 

    close($sock); 
    alarm 0; 
}; 
alarm 0; # race condition protection 
print "Error: timeout." if ([email protected] && [email protected] =~ /Timed Out/); 
print "Error: Eval corrupted: [email protected]" if [email protected]; 

并运行它:

[email protected]:~/playpen$ perl server.pl& 
[1] 9175 
[email protected]:~/playpen$ time perl test2.pl 
Error: timeout.Error: Eval corrupted: Timed Out at test2.pl line 3. 

real 0m2.040s 
user 0m0.020s 
sys   0m0.010s 

是的,这2秒后如预期超时。

+1

'Timeout'属性不会被忽略,但它被用在'IO :: Socket'的构造函数中,而不是'IO :: Socket :: INET'。尽管如此,这是一个很好的解决方法,Windows需要类似的东西。 – mob 2010-08-25 22:41:08

+0

这是真的,但它的使用被注释掉在IO :: Socket :: INET的配置子部分中。 AFAICS已设置,但从未在:: INET中使用过。 – 2010-08-25 22:48:47

+0

谢谢,这对我有用。但是,为什么这部分在源代码中有所评论? – code2be 2010-08-25 23:23:18

相关问题