Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl:如何在X秒后获得IO::Socket::INET超时?_Perl_Sockets_Networking_Inet - Fatal编程技术网

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

Perl:如何在X秒后获得IO::Socket::INET超时?,perl,sockets,networking,inet,Perl,Sockets,Networking,Inet,我正在尝试使用无效端口连接到某个主机,我希望在X秒后获得超时。怎么做 我的代码: $sock = new IO::Socket::INET( PeerAddr => $_[0], PeerPort => $_[1], Proto => 'tcp', Timeout => 2 ); 如果你检查代码,你会看到(我从我的Ubuntu 10.04复制了它): 因此,它忽略了2秒超时,并运行了整整5秒 另一个不

我正在尝试使用无效端口连接到某个主机,我希望在X秒后获得超时。怎么做

我的代码:

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

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

因此,它忽略了2秒超时,并运行了整整5秒

另一个不耐烦的客户:

# 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);
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 ( $@ && $@ =~ /Timed Out/ );
print "Error: Eval corrupted: $@" if $@;

是的,正如预期的那样,2秒后超时。

使用 IO::套接字::超时

如下图所示,它就像一个符咒

use IO::Socket::Timeout;
my $socket = IO::Socket::INET->new( Timeout => 2 );
IO::Socket::Timeout->enable_timeouts_on($socket);
$socket->read_timeout(0.5);    # These will work
$socket->write_timeout(0.5);   # These will work

Timeout
属性不会被忽略,但它用于
IO::Socket
的构造函数中,而不是
IO::Socket::INET
。这是一个很好的解决方法,类似的东西对于Windows是必要的。这是真的,但是它的使用在IO::Socket::INET的configure子部分中被注释掉了。AFAICS它已设置,但从未在::INET中使用。谢谢,这对我很有用。但是,为什么在源代码中对该部分进行了注释?请注意,示例中的第二个
报警0
调用本身不是“竞争条件保护”。相反,此技术(即,
eval{alarm$n;…;alarm 0;};alarm 0
)旨在从用户安装的ALRM处理程序以外的对象的
die()
s代码中恢复,该处理程序将退出
eval{}
块,而不会取消挂起的报警。(当然,本案中的恢复本身就很快,但这是另一回事。)问题中的代码适用于我。也许他们修好了。
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
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 ( $@ && $@ =~ /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
use IO::Socket::Timeout;
my $socket = IO::Socket::INET->new( Timeout => 2 );
IO::Socket::Timeout->enable_timeouts_on($socket);
$socket->read_timeout(0.5);    # These will work
$socket->write_timeout(0.5);   # These will work