2011-01-26 41 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()能夠完成這項工作,但我無法在這裏給出肯定的答案。