当BufReader
用于std::io::BufReader
给定(字节)定界符时,tokio::net::TcpStream
上的read_until
的单个实例会导致数据丢失吗?
也就是说,在我将BufReader
用于以下用途之后,
let buffer = Vec::new();
let reader = BufReader::new(tcp_stream);
tokio::io::read_until(reader, delimiter, buffer)
.map(move |(s, _)| s.into_inner())
后面的tokio::io::read
使用同一流是否会返回实际上超出定界符+ 1的数据,从而导致数据丢失?
我有一个问题(和complete reproducible example on Linux)无法解释上述假设是否正确。
我有一个TCP服务器,该服务器应该在多个并发请求之后将文件的内容发送到多个TCP客户端。
有时,使用始终相同的输入,客户端接收的数据少于预期,因此传输失败。
该错误不会100%地出现(也就是说,某些客户端请求仍然成功),但是在tcp_client.rs
中定义了100次尝试后,至少其中之一总是可重复的。 / p>
客户端和服务器之间传输的数据顺序由以下组成:
仅当涉及步骤1、2和3时,此问题才可重现,否则它将按预期工作。
当此tokio::io::read
(用于读取文件内容)返回0时,将引发错误,就好像服务器已关闭连接,即使服务器实际上已启动并正在运行,并且所有数据都已发送(在tokio::io::copy
之后有一个断言,我使用数据包嗅探器检查了TCP数据包)。顺便说一句,在我的所有运行中,错误发生前读取的数据量始终大于预期的95%。
最重要的是common.rs
模块定义了2个不同的read_*
函数:
read_until
当前正在使用。read_exact
未使用。 2的逻辑相同,他们需要读取请求/响应(并且客户端和服务器都可以更新为使用一个或另一个)。令人惊讶的是,仅当使用tokio::io::read_until
时tokio::io::read_exact
正常工作时,该错误才会出现。
除非我滥用tokio::io::read_until
或实现中存在错误,否则我希望两个版本都能正常工作。相反,我看到的是this panic的出现,因为某些客户端无法读取服务器发送的所有数据。
答案 0 :(得分:2)
是的。 documentation for BufReader
(重点是我的)中对此进行了描述:
放下
BufReader
时,其缓冲区的内容将被丢弃。
下一个句子是正确,但不够广泛:
在同一流上创建
BufReader
的多个实例会导致数据丢失。
BufReader
已从基础源读取数据并将其放入缓冲区,然后您就丢弃了缓冲区。数据不见了。