2011-01-26 72 views
5

我正在通过文档和howtos正在寻找正确使用IO :: Select网络套接字通信方面。我认为我的脑袋大部分都被缠住了。我该如何做适当的IO :: Select错误处理?

但是,我仍然对正确的错误处理很模糊。假设我在对象内部运行以下代码。是的,我意识到它很混乱,我应该将IO :: Select整合到对象中,而不是整个套接字本身,我不应该每次都通过循环重新创建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; 
} 
  • 我需要被检查从recv的回报,或者是会影响它会被显示出来的IO ::选择对象错误?
  • 我正确处理超时,还是我的逻辑设置错了?
  • IO :: Socket提到套接字文件句柄上存在的异常,用于带外错误和其他问题。我是否应该在发生超时时检查它?怎么样?或者它不重要,可以忽略?
  • 是否有任何其他异常情况我应该处理正确的行为?
+0

你为什么期望收集“最小长度”的数据?如果sock()返回一个文件句柄数组,你会以随机顺序从所有套接字中获得混合响应 - 是吗? – Dallaylaen 2011-01-27 11:30:13

+0

我期望收集的数据的最小长度,因为这个远程主机正在响应命令。我没有关闭整个缓冲区,而是关闭了一个字节,以确定下一个块的长度,一个块,并持续到通信编码结束。 – Oesor 2011-01-27 12:05:32

回答

1

1)我会检查以防万一。说到选择(2),defensive programming是你的朋友。

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

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

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

相关问题