无法超时

时间:2012-07-17 12:14:06

标签: perl

我正在使用以下代码。我希望超时并在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();

1 个答案:

答案 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秒,......你明白了。)