TcpStream上的BufReader :: lines()停止迭代

时间:2015-09-06 12:55:24

标签: tcp rust

我有一个相当简单的代码,使用TcpStreamSslStream围绕它,逐行读取套接字BufReader。有时迭代器会停止使用Ok(0)

返回任何数据
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);

就我所见,循环只是随机停止,并且没有理由相信socket是在服务器端关闭的。在循环结束后调用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!();
    }
}

1 个答案:

答案 0 :(得分:1)

令人惊讶的是,这是一个&#34;默认超时&#34;在客户端我猜(套接字正在进入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数据包,下一次迭代完全按预期工作。