问题背景
新手在学习 Rust 程序语言设计,https://kaisery.github.io/trpl-zh-cn/ch20-01-single-threaded.html
这里有一处说明:
接下来,需要实际读取流。这里分两步进行:首先,在栈上声明一个 buffer 来存放读取到的数据。这里创建了一个 512 字节的缓冲区,它足以存放基本请求的数据并满足本章的目的需要。如果希望处理任意大小的请求,缓冲区管理将更为复杂,不过现在一切从简。接着将缓冲区传递给 stream.read ,它会从 TcpStream 中读取字节并放入缓冲区中。
请教,如果想使用 TcpStream 处理任意大小请求,应该如何实现?
目前已经做的
google 上按照 rust TcpStream 关键字搜索,没有看到有提到这个问题的,都是引用原书。
1
共 4 条评论, 1 页
评论区
写评论read_to_end
就是从源读取直到遇到EOF。但是实际上又不是这么简单的。一般来说上层的协议比如HTTP,发送端并不是一次把数据都发送完毕然后直接发送EOF。它是发送端发送数据(请求)、接收端发送数据(响应)、发送端收到所有数据发送EOF关闭连接(读取响应)、接收端收到EOF关闭连接。
所以作为服务端的话,TcpStream在读取的时候要检查是否请求进来了,如果进来了就得及时响应。
eg:
read与read_to_end都是std::io::Read这个trait里的方法,返回值为Result, 是用Result包裹的实际读取到的字节大小,需要通过unwrap或使用?语法糖简写的match表达式才能拿到usize。
实际应用中咱们不再用std::net了,要用tokio/async-std,采用async/await来干活。
先开一个空间自动增长的u8缓冲区:
接下来有两种方法拿到incoming_bytes:
如果长度不大,一次读完:
如果长度很大,开一个分段缓冲区,loop读取:
TCP是连续的字节流,分割成单独的请求是应用层协议的事情。一般的应用层协议都会有一个请求头,其中有字段指定请求的长度。在读取头部之后知道了请求的长度,可以创建一个
Vec<u8>
或者Box<[u8]>
或者String
来继续读取请求体的数据。