Perl:如何在X秒后获得IO :: Socket :: INET超时?

前端之家收集整理的这篇文章主要介绍了Perl:如何在X秒后获得IO :: Socket :: INET超时?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用无效端口连接到某个主机,我想在X秒后获得超时.怎么做 ?

我的代码

  1. $sock = new IO::Socket::INET(
  2. PeerAddr => $_[0],PeerPort => $_[1],Proto => 'tcp',Timeout => 2
  3. );

解决方法

如果你检查你会看到的代码(我从我的Ubuntu 10.04复制它):
  1. my $timeout = ${*$sock}{'io_socket_timeout'};
  2. # my $before = time() if $timeout;
  3.  
  4. undef $@;
  5. if ($sock->connect(pack_sockaddr_in($rport,$raddr))) {
  6. # ${*$sock}{'io_socket_timeout'} = $timeout;
  7. return $sock;
  8. }
  9.  
  10. return _error($sock,$!,$@ || "Timeout")
  11. unless @raddr;
  12.  
  13. # if ($timeout) {
  14. # my $new_timeout = $timeout - (time() - $before);
  15. # return _error($sock,# (exists(&Errno::ETIMEDOUT) ? Errno::ETIMEDOUT() : $EINVAL),# "Timeout") if $new_timeout <= 0;
  16. # ${*$sock}{'io_socket_timeout'} = $new_timeout;
  17. # }

显然超时的东西被注释掉了,以便明白它被忽略的原因.

我发现了一个post年约会,从2003年开始讨论.一个建议(在底部)是在一个eval块中打开套接字,它被一个报警信号终止:

  1. eval {
  2. local $SIG{ALRM} = sub { die 'Timed Out'; };
  3. alarm 3;
  4. my $sock = IO::Socket::INET->new(
  5. PeerAddr => inet_ntoa( gethostbyname($host) ),PeerPort => 'whois',## timeout =>,);
  6. $sock->autoflush;
  7. print $sock "$qry\015\012";
  8. undef $/; $data = <$sock>; $/ = "\n";
  9. alarm 0;
  10. };
  11. alarm 0; # race condition protection
  12. return "Error: timeout." if ( $@ && $@ =~ /Timed Out/ );
  13. return "Error: Eval corrupted: $@" if $@;

不是很优雅,但如果它有效……

让我们用慢速服务器和不耐烦的客户端来验证:

  1. # Impatient Client
  2. use IO::Socket::INET;
  3.  
  4. $sock = new IO::Socket::INET(
  5. PeerAddr => "localhost",PeerPort => "10007",Timeout => 2,);
  6.  
  7. print <$sock>;
  8.  
  9. close($sock);
  10.  
  11.  
  12. # SlowServer
  13. use IO::Socket::INET;
  14.  
  15. $sock = new IO::Socket::INET(
  16. LocalAddr => "localhost",LocalPort => "10007",Listen => 1,Reuse => 1,);
  17.  
  18. $newsock = $sock->accept();
  19. sleep 5;
  20.  
  21. #while (<$newsock>) {
  22. # print $_;
  23. #}
  24. print $newsock "Some Stuff";
  25. close($newsock);
  26. close($sock);

如果我们运行这个:

  1. pti@pti-laptop:~/playpen$perl server.pl&
  2. [1] 9130
  3. pti@pti-laptop:~/playpen$time perl test.pl
  4. Some Stuff[1]+ Done perl server.pl
  5.  
  6. real 0m5.039s
  7. user 0m0.050s
  8. sys 0m0.030s

所以它忽略了2秒超时并运行了整整5秒.

现在另一个不耐烦的客户:

  1. use IO::Socket::INET;
  2. eval {
  3. local $SIG{ALRM} = sub { die 'Timed Out'; };
  4. alarm 2;
  5. $sock = new IO::Socket::INET(
  6. PeerAddr => "localhost",);
  7.  
  8. print <$sock>;
  9.  
  10. close($sock);
  11. alarm 0;
  12. };
  13. alarm 0; # race condition protection
  14. print "Error: timeout." if ( $@ && $@ =~ /Timed Out/ );
  15. print "Error: Eval corrupted: $@" if $@;

并运行它:

  1. pti@pti-laptop:~/playpen$perl server.pl&
  2. [1] 9175
  3. pti@pti-laptop:~/playpen$time perl test2.pl
  4. Error: timeout.Error: Eval corrupted: Timed Out at test2.pl line 3.
  5.  
  6. real 0m2.040s
  7. user 0m0.020s
  8. sys 0m0.010s

是的,这个超时2秒后如预期的那样.

猜你在找的Perl相关文章