如何进行正确的IO ::选择错误处理?

Oes*_*sor 5 io perl select

我正在浏览docs和howtos,我发现在网络套接字通信方面正确使用IO :: Select.我想我的大部分都被我的脑袋缠住了.

但是,我仍然对正确的错误处理有点模糊.假设我有类似于在对象内运行的以下代码.是的,我确实意识到它很乱,我应该将IO :: Select集成到对象而不是套接字fh本身,我不应该重新创建IO :: Select每次循环,我都在迭代什么只能永远是一个返回的文件句柄等.但是,这使示例简单.

这只是连接到服务器的客户端,但我希望能够正确处理网络级错误(如丢包).

编辑:$self->sock()只返回一个打开的IO :: Socket :: INET套接字.

sub read {
    my $self = shift;
    my($length) = @_;   ### Number of bytes to read from the socket

    my $ret;

    while (length($ret) < $length) {
        my $str;

        use IO::Select;
        my $sel = IO::Select->new($self->sock());

        if (my @ready = $sel->can_read(5)) {  ### 5 sec timeout
          for my $fh (@ready) {
            my $recv_ret = $fh->recv($str, $length - length($ret));
            if (!defined $recv_ret) {
              MyApp::Exception->throw(
                message => "connection closed by remote host: $!",
              );
            }
          }
        }
        else {
          ### Nothing ready... we timed out!
          MyApp::Exception->throw(
                  message => "no response from remote host",
             );
        }
        $ret .= $str;
      }

      return $ret;
}
Run Code Online (Sandbox Code Playgroud)
  • 我是否需要检查recv的返回,或者是否会影响它将出现在IO :: Select对象中?
  • 我是否正确处理超时,或者我的逻辑设置错了?
  • IO :: Socket提到了套接字文件句柄上存在的异常,用于带外错误和其他问题.如果超时,我应该检查这个吗?怎么样?或者它不重要而且可以忽略不计?
  • 是否有任何其他例外情况我应该处理正确的行为?

Dal*_*aen 1

1)我会检查以防万一。当谈到 select(2) 时,防御性编程是你的朋友。

2) 假设您需要 2048 字节,并且远程主机每 5 秒发送一个字节。您刚刚挂起 10K 秒 = 3 小时。那是你要的吗?

我会用alarm 5and$SIG{ALRM} = sub {$stop = 1;}代替。

3和4)根据我的经验,只是read() while select()完成工作,但我不能在这里给出肯定的答案。