我正在浏览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; }
>我是否需要检查recv的返回,或者是否会影响它将出现在IO :: Select对象中?
>我是否正确处理超时,或者我的逻辑设置错误了?
> IO :: Socket提到了套接字文件句柄上存在的异常,用于带外错误和其他问题.如果超时,我应该检查这个吗?怎么样?或者它不重要而且可以忽略不计?
>我是否应该为正确的行为处理任何其他异常情况?
解决方法
1)我会检查以防万一.当谈到选择(2)时,defensive programming是你的朋友.
2)假设您需要2048个字节,远程主机每5秒发送一个字节.你刚挂了10K秒= 3个小时.那是你要的吗?
我会使用闹钟5和$SIG {ALRM} = sub {$stop = 1;}代替.
3和4)根据我的经验,只有read()而select()完成工作,但我不能在这里给出一个肯定的答案.