tcp - TCPStream 如何知道消息何时完成?
问题描述
据我了解,TCPStream
不知道何时从客户端收到完整的消息,但信息以字节流的形式到达。
但是,当我在 Rust 中执行标准的“Hello World”TCPStream
示例时,我正在从流中读取完整的 HTTP 消息。当我发送两条或更多条消息时,它们将相应地分开。
这怎么可能?
use std::io::prelude::*;
use std::net::TcpListener;
use std::net::TcpStream;
fn main() {
let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
for stream in listener.incoming() {
let stream = stream.unwrap();
handle_connection(stream);
}
}
fn handle_connection(mut stream: TcpStream) {
let mut buffer = [0; 512];
stream.read(&mut buffer).unwrap();
println!("{}", String::from_utf8_lossy(&buffer[..]));
}
当我减小缓冲区大小时,HTTP 消息会被剪切,更新的消息会从头开始。我会以某种方式假设我必须自己管理结束和开始一条新的 HTTP 消息?
解决方案
在非常低的级别上,客户端使用基本的 Unixwrite(socket, buf, nbytes)
操作将字节放入套接字,而服务器则使用nread =
read(socket, buf, maxbytes)
从套接字中提取字节。
当read()
和write()
与套接字一起使用时,它们不保证任何关于将 a 拆分write()
为多个read()
s 或将多个 s 合并write()
为一个 big的行为read()
。任何事情都可能发生,只要客户端写入的字节最终将由服务器按照客户端写入它们的顺序读取(假设网络连接由于某种原因没有断开)。
在您的特定情况下,客户端可能发出了两个write()
调用,这些调用在 TCP 层中被转换为两个相应的数据包。服务器进程正在等待read()
呼叫。服务器操作系统设法唤醒服务器进程,并在第二个数据包到达之前将第一个数据包的内容提供给它,或者以其他方式通过服务器操作系统。因此,服务器进程发现自己处于一个方便的位置,可以处理一个完整的 HTTP 请求。
推荐阅读
- emacs - 如何在 Emacs 中更改某个字符串的颜色?
- reactjs - handleChange = (e) => {} 和 handleButtonClick = () => | 为什么有'e'必须在()内,而有些不需要字母?
- javascript - 通过 vba 从 ie 触发 javascript
- python - “gensim.models.word2vec”没有属性“KeyedVectors”
- c++ - 在 std::unordered_map 中插入新的键/值对会导致“超出范围”异常
- spring - 表单提交后转发到 Spring Controller 中的 JSP
- javascript - 转换多个打开时间和减少单个打开时间的问题
- sql - 根据大于子句更新 Select 中的值
- heroku - 将 Flask 应用程序部署到 Heroku 的困难
- java - 使用 Webflux 实现 POST