我可以在Rust中很容易地创建一个TcpListener和TcpAcceptor,但是我不太了解它们的作用。监听器似乎并没有真正监听,而仅仅是接收者的设置结构。
let tcp_listener = TcpListener::bind(addr);
let mut acceptor = tcp_listener.listen();
drop(acceptor);
让我感到困惑的一件事是挂断电话。我不知道drop在哪里定义,我已经搜索了一些标准库,但只能将其作为特征方法。
另外,为什么放弃接受者会停止收听?那不应该只是停止接受吗?当然,您想删除监听器。为什么甚至还有一个TcpListener,因为接受者似乎可以做所有事情?
最佳答案
简而言之,在BSD套接字框架中,这是服务器启动的通常方式:
socket()
系统调用创建一个主服务器套接字; bind()
系统调用将主套接字绑定(bind)到特定的地址/端口; listen()
系统调用来“启动”主套接字;从这一刻起直到主 socket 关闭为止,它将接管绑定(bind)到的端口并监听传入的连接; accept()
;该调用将阻塞,直到某些客户端连接,然后它将返回一个新的套接字,该套接字表示与此客户端的连接;与该客户端的所有通信都通过此套接字;交互结束后,应关闭此套接字。 在Rust中,TCP堆栈使用的主要方法的命名遵循标准的BSD套接字命名,但是,Rust API更抽象,因此隐藏了一些底层概念。
TcpListener::bind()
创建一个新的主套接字(socket()
系统调用)并将其绑定(bind)到提供的地址(bind()
系统调用)。它返回一个对象TcpListener
,该对象将主套接字封装为“已创建但未处于 Activity 状态”。TcpListener
提供了一种称为TcpListener::listen()
的方法,该方法包装了listen()
系统调用并“激活”服务器套接字。它返回一个新对象TcpAcceptor
,它提供了方便的接口(interface)来接受传入的连接。它表示处于“创建和 Activity ”状态的主套接字。TcpAcceptor
依次具有几种方法(TcpAcceptor::incoming()
和TcpAcceptor::accept()
),这些方法包装accept()
系统调用并阻止当前任务,直到某些客户端建立连接导致TcpStream
(代表客户端套接字的对象)为止。与所有套接字关联的所有OS资源在调用其析构函数时都将释放。 Rust中的析构函数可以与任何自定义结构相关联。要将析构函数添加到您的结构中,您必须为其实现
Drop
特性。当此类结构的实例超出范围时,将调用析构函数,例如:struct Test { value: int }
impl Drop for Test {
fn drop(&mut self) {
println!("Dropping Test: value is {}", self.value);
}
}
fn main() {
let test = Test { value: 10 };
// main ends, `test` goes out of scope
}
该程序打印
Dropping Test: value is 10
。对于在其上实现了
Drop
特性的结构,重要的是它们不是隐式可复制的。这意味着当此类结构的实例传递给函数参数或分配给不同的变量时,它们会从其原始位置移出,也就是说,您将无法再通过其原始变量使用它们。例如(使用上面的Test
定义):let test = Test { value: 10 };
let test2 = test;
println!("{}", test.value); // error: use of moved value: `test`
drop()
模块中定义了让您感到困惑的core::mem
函数; here是其文档。它的实现非常简单。它看起来像这样:fn drop<T>(x: T) { }
它什么都不做!但是因为它接受按值的参数,所以该参数被移到了
drop()
调用中。然后,由于函数返回,因此所述参数立即超出范围。如果T
有关联的析构函数,它将在此处运行。因此,drop()
本质上是一个“黑洞”:放入其中的所有内容均被破坏(除非它是隐式可复制的)。该语言的一个很好的特性是这种函数可以用普通的Rust编写,而无需任何魔术。实际上,
drop()
几乎没有用,因为所有析构函数始终在相应对象超出范围时运行。当需要一些具有可破坏资源的复杂逻辑时,它有时很有用,但这种情况很少发生。关于sockets - Rust中TcpListener和TcpAcceptor的职责,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24023795/