Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Networking 在连接关闭之前,TCP流不会从读取返回_Networking_Tcp_Rust - Fatal编程技术网

Networking 在连接关闭之前,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 =

我正在尝试用标准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 = 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
的内容。不管怎样,我修复了代码,添加了缺失的部分,并对其进行了测试,结果正如预期的那样。