我正在try 用Rust编写一个echo服务器.

use std::net::{TcpStream, TcpListener};
use std::io::prelude::*;

fn main() {
    let listener = TcpListener::bind("0.0.0.0:8000").unwrap();
    for stream in listener.incoming() {
        let stream = stream.unwrap();
        println!("A connection established");
        handle_connection(stream);
    }

}

fn handle_connection(mut stream: TcpStream) {
    let mut buffer = [0; 512];

    stream.read(&mut buffer).unwrap();

    println!("Request: {}", String::from_utf8_lossy(&buffer[..]));
    stream.write(&buffer[..]).unwrap();
    stream.flush().unwrap();
}

nc localhost 8000的第一个请求按预期工作,但后续请求没有.我做错了什么?服务器读取客户端请求的方式有问题吗?虽然服务器端没有错误.

我通过在终端上键入数据来发送数据:

$ nc localhost 8000
hi
hi
hello
# no response
# on pressing enter
Ncat: Broken pipe.

推荐答案

当您写入另一端已关闭的流时,会出现"断管"消息.在您的示例中,handle_connection routine 从客户端读取一个缓冲区,将其复制回客户端,然后返回,这将关闭流.当您像这样从终端运行netcat时,终端默认为行缓冲,因此您键入的每一行都将作为一次写入发送到服务器.

第一行被服务器发送、读取、 echo ,然后服务器关闭连接.Netcat获取第二行,将其写入套接字,并获取"断管",因为服务器已关闭连接.

如果希望服务器读取多条消息,则需要进行handle_connection例行循环,从流中读取消息,直到获得EOF.

Rust相关问答推荐

关联类型(类型参数)命名约定

如何容器化Linux上基于Rust的Windows应用程序的编译过程?

如何在原始字符串中转义";#和#";

在自身功能上实现类似移动的行为,以允许通过大小的所有者进行呼叫(&;mut;self)?

为什么Rust函数的移植速度比C++慢2倍?

防止cargo test 中的竞争条件

在析构赋值中使用一些现有绑定

允许 rust 迹 struct 条目具有多种类型

Rust wasm 中的 Closure::new 和 Closure::wrap 有什么区别

在什么情况下 `..._or()` 比 `..._or_else(|| {})` 更好,为什么?

.在 Rust 模块标识符中

Rust,如何从 Rc> 复制内部值并返回它?

通过写入 std::io::stdout() 输出不可见

为什么我们有两种方法来包含 serde_derive?

Rust并发读写引起的死锁问题

在 Rust 中使用 `SecTrustSettingsSetTrustSettings` 绑定导致 `errSecInternalComponent`

判断对象是 PyDatetime 还是 Pydate 的实例?

使用 serde_json 进一步处理字段

如何在 Rust 中编写修改 struct 的函数

匹配结果时的简洁日志(log)记录