Rust 中的 TCP 连接

bas*_*ndo 3 tcp rust

所以我试图更好地理解简单的 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)

我不明白的是每次建立连接时线程如何处理服务器。是不是就像设置多台服务器一样?如何处理进出服务器的数据包?您如何处理断开的连接?

pro*_*-fh 6

这就是典型的多线程TCP服务器架构。

  • 主线程在侦听套接字上循环以连接accept()每个新连接(此处的循环.incoming()),
  • 一旦连接可用(.incoming()产生一个新元素),我们就启动一个新线程,该线程将负责该特定连接上发生的所有对话,
  • 之后,主线程立即准备好accept()任何潜在的新连接(上的下一次迭代.incoming()),即使前一个线程花费很长时间与客户端对话。

在任何时候,线程数都是已连接客户端数+1(+1是隐式主线程,专门用于接受新连接)。

处理断开连接是每个单独线程的关注点(关于它处理的唯一连接)。

这个 TCP 服务器架构绝对不是 Rust 特有的。Rust 只是将底层系统调用(socket()bind()listen()accept()...)封装在一个漂亮的 API 中。