我正在使用以下代码。我希望超时并在20秒后关闭连接,尝试使用警报但没有任何效果。这是我的代码:
my $socket_resp = IO::Socket::INET->new(Blocking => 0, LocalPort => $comm_port, Proto => 'udp', Timeout => 2);
$socket_resp->setsockopt(SO_RCVTIMEO, SO_RCVTIMEO, 10);
print "Waiting for Response On Port $comm_port\n";
while (my $recieved_data = $socket_resp->getline()) {
chomp($recieved_data);
print "$recieved_data\n";
if ($recieved_data =~ m/^done/i) {
last;
}
}
$socket_resp->close();
答案 0 :(得分:0)
按照other question中的建议,将整个读取循环包含在警报中很可能会执行您想要的操作。您没有向我们展示代码,因此我们不知道您之前的尝试失败的原因。
也就是说,SO_RCVTIMEO也可以工作,虽然有点不同。
在这种情况下,您需要阻止而不是非阻塞套接字。您还需要setsockopt
正确,这需要SOL_SOCKET和pack()
struct timeval
:
my $s = IO::Socket::INET->new(Proto => 'udp', ...); # N.B.: blocking
$s->setsockopt(SOL_SOCKET, SO_RCVTIMEO, pack('l!l!', 20, 0)); # N.B.: pack()
while (<$s>) {
...
}
现在,对于read()
的每个底层调用,上面等待20秒,这可能超过返回给您的应用程序的行的数量。也就是说,如果我将您的应用程序"foo\n"
发送到一个数据报中,然后什么都没有,那么您将在20秒后超时。但是,我可能会发送"f"
,然后等待19秒,"o"
,然后等待19秒,"o"
,然后等待19秒,......你明白了。)