【问题标题】:TCP Connections Within RustRust 中的 TCP 连接
【发布时间】:2021-10-24 04:16:32
【问题描述】:

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

服务器通过接受来自给定套接字的传入连接来工作。在产生需要线程之后,您重新定义流变量,以便您可以将其更改为您想要的任何内容。然后,您可以随时写入该变量。

然后假设有一个看起来像这样的客户端:

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

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

【问题讨论】:

  • 多线程解决方案、轮询解决方案和异步解决方案,可以使用这两种解决方案来实现。
  • 所有这些有什么区别?

标签: rust tcp


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 那么你使用多线程而不是单线程是有原因的吗?我想如果它是单线程的,那么将很难接受新的连接。还有一个 TCP 连接意味着打开,交换一些信息而不是关闭吗?
  • @bastwendo 是的,多线程解决方案很容易编写(每个线程只要需要就阻塞,而不用担心任何其他传入连接),用于快速而肮脏的实验,但它不会扩大规模( async/select 解决方案会更好,但更难生产)。
猜你喜欢
  • 2021-05-26
  • 2015-05-02
  • 2019-02-25
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 2011-07-19
  • 2019-01-28
  • 2016-03-24
相关资源
最近更新 更多