rust 为什么TcpStream和生成的TcpStream的文件描述符不同?

x6yk4ghg  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(110)

我试图研究文件描述符以及它们如何与Rust中的tcp连接交互,我对Rust编程和Unix都很陌生。
最后,我想通过匹配文件描述符来将一些程序的stdio绑定到tcp发送/接收。现在,我只想了解文件描述符是如何分配的,以及为什么它们会得到不同的值。
我写了这个简单的代码来做实验:

use std::{
    net::TcpListener,
    os::fd::AsFd
};

fn main() {
    let listener = TcpListener::bind("0.0.0.0:1024").unwrap();
    println!("Listener fd: {:?}", listener.as_fd());
    for stream in listener.incoming() {
        let stream = stream.unwrap();
        println!("Stream fd: {:?}", stream.as_fd());
    }
}

字符串
当我运行这个程序时,我得到的第一行是:

Listener fd: BorrowedFd { fd: 3 }


当我随后向tcp侦听器发送一些数据时,它会像我期望的那样打印出如下行:

Stream fd: BorrowedFd { fd: 4 }


我想了解的是:

  • 为什么文件描述符不同?
  • 每个文件描述符对应于什么,即使用3对应于连接的传入数据,使用4对应于我可以写回流的数据?
oyxsuwqo

oyxsuwqo1#

文件描述符是内核向某些功能公开的不透明句柄。在您的情况下,文件描述符#3由socket()bound获取到端口。这反过来允许您在其上调用accept()以获取更多文件描述符(例如您的#4),这些描述符可用于与不同连接的客户端进行通信。
文件描述符#4是你对连接的对等体的句柄。它支持像read()write()这样的操作(以及许多其他操作,如select())。这些操作通常在对应于打开文件的文件描述符上提供,这就是Unix提供多态性的方式。
对同一个文件描述符的读写操作不会相互干扰,因为它们是不同的操作,操作系统足够聪明,可以区分它们。在数字4后面,内核保留了一个完整的数据结构,其中包含单独的读写缓冲区,控制流标志等等。只有在用户空间中,它才被表示为一个数字,你可以把它看作是内核中保存的一个表的索引。

相关问题