0

我正在使用以下代码。我想在 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();
4

1 回答 1

0

正如另一个问题中所建议的那样,将整个读取循环包装在警报中很可能会满足您的需求。您没有向我们展示代码,因此我们不知道您之前的尝试失败的原因。

也就是说,SO_RCVTIMEO 也可以工作,尽管有点不同。

在这种情况下,您需要一个阻塞而不是非阻塞套接字。您还希望setsockopt正确,这需要 SOL_SOCKET 和pack()ing a 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>) {
  ...
}

现在,对于每个对 的底层调用,上述等待 20 秒read(),这可能超过返回给您的应用程序的行数。也就是说,如果我"foo\n"在一个数据报中发送您的应用程序然后什么也没发送,您将在 20 秒后超时。但是,我可能会发送"f",然后等待 19 秒,"o",然后等待 19 秒,"o",然后等待 19 秒,......你明白了。)

于 2012-07-18T15:09:29.260 回答