2015-09-06 29 views
4

我有一個合理簡單的代碼,它使用TcpStreamSslStream圍繞它,逐行讀取套接字BufReader。有時迭代器只是停止與Ok(0)返回任何數據:BufReader :: TcpStream上的行()停止迭代

let mut stream = TcpStream::connect((self.config.host.as_ref(), self.config.port)).unwrap(); 
if self.config.ssl { 
    let context = ssl::SslContext::new(ssl::SslMethod::Tlsv1_2).unwrap(); 
    let mut stream = ssl::SslStream::connect(&context, stream).unwrap(); 
    self.stream = Some(ssl::MaybeSslStream::Ssl(stream)); 
} else { 
    self.stream = Some(ssl::MaybeSslStream::Normal(stream)); 
} 

... 

let read_stream = clone_stream(&self.stream); 

let line_reader = BufReader::new(read_stream); 

for line in line_reader.lines() { 
    match line { 
     Ok(line) => { 
      ... 
     } 
     Err(e) => panic!("line read failed: {}", e), 
    } 
} 
println!("lines out, {:?}", self.stream); 

環路只是停止隨機,據我所看到的,而且也沒有理由相信套接字已關閉的服務器端。循環結束後調用self.stream.as_mut().unwrap().read_to_end(&mut buf)返回Ok(0)

有關如何處理這個問題的任何建議?我沒有得到任何Err,所以我可以認爲套接字仍然活着,但我不能從它讀取任何東西。什麼是套接字的當前狀態,我應該如何繼續? PS:我提供了clone_stream作爲參考的實現,正如評論者所建議的那樣。

fn clone_stream(stream: &Option<ssl::MaybeSslStream<TcpStream>>) -> ssl::MaybeSslStream<TcpStream> { 
    if let &Some(ref s) = stream { 
     match s { 
      &ssl::MaybeSslStream::Ssl(ref s) => ssl::MaybeSslStream::Ssl(s.try_clone().unwrap()), 
      &ssl::MaybeSslStream::Normal(ref s) => ssl::MaybeSslStream::Normal(s.try_clone().unwrap()), 
     } 
    } else { 
     panic!(); 
    } 
} 
+0

*沒有理由相信套接字已關閉服務器端* - 你能證明這種方式或其他?在關閉的套接字上讀取零字節是正常情況,聽起來就像你擁有的一樣。 – Shepmaster

+1

請儘量減少測試用例並生成[MCVE](/ help/mcve)。實際上,我們不知道clone_stream是什麼。另外,這*可能僅僅是SSL封裝中的一個錯誤,所以請嘗試刪除條件並將其固定到其中一個。 – Shepmaster

回答

1

出人意料的是,這是一個「默認的超時」客戶端我猜(插座正在進入CLOSE_WAIT狀態)。

stream.set_read_timeout(Some(Duration::new(60*5, 0))); 
stream.set_write_timeout(Some(Duration::new(60*5, 0))); 

該取得的迭代器失敗,ErrorKind::WouldBlock上超時,此時我添加了一個代碼,以通過網絡發送ping數據包,下一個迭代工作完全一樣:

我通過首先將固定它預期。