在 BufReader 中读取一行会创建一个无限循环
Reading a line in a BufReader creates an infinite loop
我正在尝试使用 Rust 中的 TcpListener 在网络上接收消息(服务器端)。
这是服务器代码:
// Instanciate TcpListener
let server = TcpListener::bind("0.0.0.0:52001").expect("Could not bind");
match server.accept() { // Waiting new connection from a client
Ok((stream, addr)) => {
println!("New connection from {}", addr);
// Wrapping the stream in a BufReader
let mut reader = BufReader::new(&stream);
let mut message = String::new();
loop { // Entering the loop when a client is connected
reader.read_line(&mut message).expect("Cannot read new line");
println!("message received: {}", message);
message.clear();
}
}
Err(e) => {
println!("Fail: {:?}", e)
}
}
这是我的 Kotlin 客户端:
Socket("192.168.134.138", 52001).use { client ->
client.getOutputStream().use { out ->
out.write("test\n".toByteArray())
}
}
while(true) {
Thread.sleep(15_000)
}
客户端发送以下行:test\n
并以换行符结束供服务器读取。
预期的行为是在服务器端打印 message received: test
然后服务器在 read_line()
指令处等待下一行
之所以有效,是因为我收到了 test
,但 read_line()
方法似乎既没有阻止也没有等待另一条消息。所以它创建了一个无限循环。所以在终端我得到:
New connection from 192.168.134.123:7869
message received: test
message received:
message received:
message received:
message received:
Process finished with exit code 130 (interrupted by signal 2: SIGINT)
而且我必须强行停止程序。
有什么想法吗?
要检测流的结尾,您需要检查 read_line()
是否返回 Ok(0)
:
来自docs:
If this function returns Ok(0)
, the stream has reached EOF.
loop { // Entering the loop when a client is connected
let mut message = String::new();
if reader.read_line(&mut message).expect("Cannot read new line") == 0 {
break;
}
println!("message received: {}", message);
}
另一种方法是使用 BufReader::lines()
迭代器:
for line in reader.lines() {
let message = line.expect("Cannot read new line");
println!("message received: {}", message);
}
这种方法效率有点低,因为它在每次迭代时都分配一个新的字符串。为了获得最佳性能,您应该分配一个 String 并像@BlackBeans 在评论中指出的那样重用它:
let mut message = String::new();
loop { // Entering the loop when a client is connected
message.clear();
if reader.read_line(&mut message).expect("Cannot read new line") == 0 {
break;
}
println!("message received: {}", message);
}
我正在尝试使用 Rust 中的 TcpListener 在网络上接收消息(服务器端)。 这是服务器代码:
// Instanciate TcpListener
let server = TcpListener::bind("0.0.0.0:52001").expect("Could not bind");
match server.accept() { // Waiting new connection from a client
Ok((stream, addr)) => {
println!("New connection from {}", addr);
// Wrapping the stream in a BufReader
let mut reader = BufReader::new(&stream);
let mut message = String::new();
loop { // Entering the loop when a client is connected
reader.read_line(&mut message).expect("Cannot read new line");
println!("message received: {}", message);
message.clear();
}
}
Err(e) => {
println!("Fail: {:?}", e)
}
}
这是我的 Kotlin 客户端:
Socket("192.168.134.138", 52001).use { client ->
client.getOutputStream().use { out ->
out.write("test\n".toByteArray())
}
}
while(true) {
Thread.sleep(15_000)
}
客户端发送以下行:test\n
并以换行符结束供服务器读取。
预期的行为是在服务器端打印 message received: test
然后服务器在 read_line()
指令处等待下一行
之所以有效,是因为我收到了 test
,但 read_line()
方法似乎既没有阻止也没有等待另一条消息。所以它创建了一个无限循环。所以在终端我得到:
New connection from 192.168.134.123:7869
message received: test
message received:
message received:
message received:
message received:
Process finished with exit code 130 (interrupted by signal 2: SIGINT)
而且我必须强行停止程序。
有什么想法吗?
要检测流的结尾,您需要检查 read_line()
是否返回 Ok(0)
:
来自docs:
If this function returns
Ok(0)
, the stream has reached EOF.
loop { // Entering the loop when a client is connected
let mut message = String::new();
if reader.read_line(&mut message).expect("Cannot read new line") == 0 {
break;
}
println!("message received: {}", message);
}
另一种方法是使用 BufReader::lines()
迭代器:
for line in reader.lines() {
let message = line.expect("Cannot read new line");
println!("message received: {}", message);
}
这种方法效率有点低,因为它在每次迭代时都分配一个新的字符串。为了获得最佳性能,您应该分配一个 String 并像@BlackBeans 在评论中指出的那样重用它:
let mut message = String::new();
loop { // Entering the loop when a client is connected
message.clear();
if reader.read_line(&mut message).expect("Cannot read new line") == 0 {
break;
}
println!("message received: {}", message);
}