加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-15 21:16:47 所属栏目:大数据 来源:网络整理
导读:我正在尝试使用无效端口连接到某个主机,我想在X秒后获得超时.怎么做 ? 我的代码: $sock = new IO::Socket::INET( PeerAddr = $_[0],PeerPort = $_[1],Proto = 'tcp',Timeout = 2 ); 解决方法 如果你检查你会看到的代码(我从我的Ubuntu 10.04复制它): my $
我正在尝试使用无效端口连接到某个主机,我想在X秒后获得超时.怎么做 ?

我的代码:

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

解决方法

如果你检查你会看到的代码(我从我的Ubuntu 10.04复制它):
my $timeout = ${*$sock}{'io_socket_timeout'};
#       my $before = time() if $timeout;

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

        return _error($sock,$!,$@ || "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;
#        }

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

我发现了一个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',## timeout =>,);
  $sock->autoflush;   
  print $sock "$qry1512"; 
  undef $/; $data = <$sock>; $/ = "n"; 
  alarm 0; 
}; 
alarm 0; # race condition protection 
return "Error: timeout." if ( $@ && $@ =~ /Timed Out/ ); 
return "Error: Eval corrupted: $@" if $@;

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

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

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

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

print <$sock>;

close($sock);


# SlowServer
use IO::Socket::INET;

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

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

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

如果我们运行这个:

pti@pti-laptop:~/playpen$perl server.pl&
[1] 9130
pti@pti-laptop:~/playpen$time perl test.pl
Some Stuff[1]+  Done                    perl server.pl

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

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

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

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

  print <$sock>;

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

?

并运行它:

pti@pti-laptop:~/playpen$perl server.pl&
[1] 9175
pti@pti-laptop:~/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秒后如预期的那样.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读