为何同一函数中使用BufWriter和BufReader时服务器无法正常工作?
为什么同一函数内用BufWriter写入后BufReader读取阻塞,拆分函数就正常?
核心原因是BufWriter的缓冲区刷新时机:
BufWriter是带缓冲的写入工具,它不会将数据立即写入底层TCP流,而是先暂存在内部缓冲区,只有满足以下条件之一时才会把数据刷到流中:
- 缓冲区被写满
- 手动调用
flush()方法 - BufWriter实例被销毁(即离开作用域触发
Droptrait)
分析Code 00的阻塞问题
在同一个函数中,my_buf_writer变量的作用域覆盖到函数结束,调用write()后,数据还留在BufWriter的缓冲区里,根本没发送给服务器。服务器没收到请求,自然不会返回响应,客户端的read_line()会一直等待换行符,导致阻塞。
分析Code 01的正常运行
当写入逻辑拆分到write_in_database函数后,函数执行完毕时,内部的my_buf_writer会离开作用域,触发Drop操作。BufWriter的Drop实现会自动调用flush(),把缓冲区里的请求数据写入TCP流,发送给服务器。服务器收到请求后返回响应,客户端的read_line()就能读到换行符,正常结束。
解决Code 00阻塞的方法
你不需要拆分函数,只需要手动刷新缓冲区即可:
fn main(){ let mut stream = TcpStream::connect("127.0.0.1:9073").unwrap(); let mut my_buf_writer = BufWriter::new(&stream); my_buf_writer.write(b"GET|1|ALL\n").unwrap(); my_buf_writer.flush().unwrap(); // 手动刷新,确保数据发送到服务器 let mut my_buf_reader = BufReader::new(&stream); let mut buffer = String::new(); println!("Reading line"); my_buf_reader.read_line(&mut buffer).unwrap(); println!("{}", buffer); }
另外,也可以使用writeln!宏,它会自动处理换行并在必要时刷新(不过仍建议根据场景确认是否需要手动flush):
writeln!(my_buf_writer, "GET|1|ALL").unwrap();
内容的提问来源于stack exchange,提问作者BeepBoopBit
相关产品推荐
相关产品推荐

