所以我试图更好地理解简单的 TCP 服务器如何在 Rust 中工作。假设我有下面的简单 TCP 服务器。
use std::io::Write;
use std::net::TcpListener;
use std::thread;
fn main() {
let listener = TcpListener::bind("127.0.0.1:9123").unwrap();
println!("listening started, ready to accept");
for stream in listener.incoming() {
thread::spawn(|| {
let mut stream = stream.unwrap();
stream.write(b"Hello World\r\n").unwrap();
});
}
}
Run Code Online (Sandbox Code Playgroud)
服务器通过接受来自给定套接字的传入连接来工作。在生成所需线程后,您可以重新定义流变量,以便可以将其更改为您想要的任何内容。然后您可以随时写入该变量。
假设有一个如下所示的客户端:
use std::net::TcpStream;
//and any other imports that you need
fn main() {
let stream = TcpStream::connect("127.0.0.1:9123").unwrap();
//Then assume that you can read and write things back to the server
Run Code Online (Sandbox Code Playgroud)
我不明白的是每次建立连接时线程如何处理服务器。是不是就像设置多台服务器一样?如何处理进出服务器的数据包?您如何处理断开的连接?
这就是典型的多线程TCP服务器架构。
accept()每个新连接(此处的循环.incoming()),.incoming()产生一个新元素),我们就启动一个新线程,该线程将负责该特定连接上发生的所有对话,accept()任何潜在的新连接(上的下一次迭代.incoming()),即使前一个线程花费很长时间与客户端对话。在任何时候,线程数都是已连接客户端数+1(+1是隐式主线程,专门用于接受新连接)。
处理断开连接是每个单独线程的关注点(关于它处理的唯一连接)。
这个 TCP 服务器架构绝对不是 Rust 特有的。Rust 只是将底层系统调用(socket()、bind()、listen()、accept()...)封装在一个漂亮的 API 中。
| 归档时间: |
|
| 查看次数: |
8057 次 |
| 最近记录: |