Networking 在连接关闭之前,TCP流不会从读取返回
我正在尝试用标准TCP套接字在Rust中实现一个简单的TCP消息传递协议。协议是这样的:Networking 在连接关闭之前,TCP流不会从读取返回,networking,tcp,rust,Networking,Tcp,Rust,我正在尝试用标准TCP套接字在Rust中实现一个简单的TCP消息传递协议。协议是这样的: [C0 FF EE]标题 [XX XX]U16LE型 [XX XX]尺寸U16LE ... (大小-8)字节的任意数据。。。 我想出了以下代码: const REQUEST_HEADER: [u8; 4] = [0xC0, 0xFF, 0xEE, 0xEE]; pub fn run_server(host: &str, port: &str) { let listener =
[C0 FF EE]标题
[XX XX]U16LE型
[XX XX]尺寸U16LE
... (大小-8)字节的任意数据。。。
我想出了以下代码:
const REQUEST_HEADER: [u8; 4] = [0xC0, 0xFF, 0xEE, 0xEE];
pub fn run_server(host: &str, port: &str) {
let listener = TcpListener::bind(format!("{}:{}", host, port))
.expect("Could not bind to the requested host/port combination.");
for stream in listener.incoming() {
thread::spawn(|| {
let stream = stream.unwrap();
handle_client(stream);
});
}
}
fn handle_client(stream: TcpStream) {
stream.set_nodelay(true).expect("set_nodelay call failed");
loop {
match get_packet(stream) {
Ok(deframed) => {
match deframed.msgid {
Some(FrameType::Hello) => say_hello(stream),
Some(FrameType::Text) => {
println!("-- Got text message: {:X?}", deframed.content);
save_text(deframed);
},
Some(FrameType::Goodbye) => {
println!("-- You say goodbye, and I say hello");
break; // end of connection
},
_ => println!("!! I don't know this packet type")
}
},
Err(x) => {
match x {
1 => println!("!! Malformed frame header"),
2 => println!("!! Client gone?"),
_ => println!("!! Unknown error")
}
break;
}
}
}
}
// Read one packet from the stream
fn get_packet(reader: TcpStream) -> Result<MyFrame, u8> {
// read the packet header in here
let mut heading = [0u8; 0x8];
match reader.read_exact(&mut heading) {
Ok(_) => {
// check if header is OK
if heading[..4] == REQUEST_HEADER
{
// extract metadata
let mid: u16 = ((heading[4] as u16) << 0)
+ ((heading[5] as u16) << 8);
let len: u16 = ((heading[6] as u16) << 0)
+ ((heading[7] as u16) << 8);
let remain: u16 = len - 0x8;
println!("-> Pkt: 0x{:X}, length: 0x{:X}, remain: 0x{:X}", mid, len, remain);
let mut frame = vec![0; remain as usize];
reader.read_exact(&mut frame).expect("Read packet failed");
let deframed = MyFrame {
msgid: FromPrimitive::from_u16(mid),
content: frame
};
Ok(deframed)
} else {
println!("!! Expected packet header but got {:X?}", heading.to_vec());
Err(1)
}
},
_ => Err(2)
}
}
当程序收到一行多条消息时,它们似乎得到了很好的处理。如果客户端发送消息并等待响应,程序将无法读取帧内容,直到再收到约16个字节。因此,程序无法向客户端发送响应
我可以看出它卡在那里,而不是其他地方,因为->Pkt
日志行显示了正确的元数据,但它不会继续进一步处理,尽管客户端已经发送了所有内容
我试着用read
替换read\u-exact
,但它一直卡在那里。一旦客户机软件断开连接,消息会突然正常处理
这是一个设计问题,还是我遗漏了一个需要更改的插座设置?我觉得没问题。也许是客户端代码中的一个问题,缓冲了它的输出?为了完全确定您可以尝试使用嗅探器捕获网络流量。@rodrigo--我已经用以下简单的python程序进行了尝试:--仍然无法使用->Pkt。。。当我用Ctrl-C退出python时,情况突然变好了。您的代码没有编译,一些关于
reader
的内容正在循环中使用。我猜这不是您正在运行的实际代码。您应该发布一个MCVE,以及您在pastebin中使用的message.bin
的内容。不管怎样,我修复了代码,添加了缺失的部分,并对其进行了测试,结果正如预期的那样,我觉得还可以。也许是客户端代码中的一个问题,缓冲了它的输出?为了完全确定您可以尝试使用嗅探器捕获网络流量。@rodrigo--我已经用以下简单的python程序进行了尝试:--仍然无法使用->Pkt。。。当我用Ctrl-C退出python时,情况突然变好了。您的代码没有编译,一些关于reader
的内容正在循环中使用。我猜这不是您正在运行的实际代码。您应该发布一个MCVE,以及您在pastebin中使用的message.bin
的内容。不管怎样,我修复了代码,添加了缺失的部分,并对其进行了测试,结果正如预期的那样。