是否可以在 Tokio 中关闭 TcpListener?

Is it possible to close a TcpListener in Tokio?

我创建了一个 tokio_core::net::TcpListener,然后调用 incoming 方法来获取传入连接流。然后,我在该流上使用 for_each 方法将其变成未来,并在事件循环中使用 运行 未来。一旦我这样做了,以后有什么办法可以从端口解除绑定吗?

如果没有,Tokio中是否还有其他API可以用来创建可以关闭的TCP服务器?

简而言之,您需要删除由 for_each 编辑的 TcpListener / Future return。

你可以:

  • 为包含应用程序其余部分状态的某些结构编写 Future 实现。结构的 Future::poll 实现然后是 poll 包含的所有 Future 状态,如果您想提前退出,则 return 是 Async::Ready。如果包含的 Futures 在它们自己的任务中包装在 oneshot::spawn 到 运行 中,这可能有助于提高性能。

    您的结构将包含一个 Option<SpawnHandle<(), ...>>。如果您想停止收听,只需将其设置为 None.

  • 通过检查一些 "global" (Arc<AtomicBool>) 标记是否继续使用 Stream::take_while
  • 来过滤 incoming
  • 在你的 for_each 处理程序结束时检查是否继续监听,否则 return 一个错误(这会停止 for_each 循环)

后两种方法仅在 seeing/handling 传入连接后停止,因此它们仅适用于繁忙的环境。

这是我最近发现的另一种选择。

您基本上需要删除 TcpListener/for_each 未来才能停止收听。由于它永远不会自己完成,只需使用 select() 将它与您控制的另一个未来(例如 oneshot::Receiver<()>)结合起来。如果侦听器完成(从不)或 oneshot 收到一个值(您可以通过向另一端发送一些内容来触发该值),则返回的未来将完成。

对于需要关闭多个东西的更复杂的程序,还有一个 watch channel,一个 Sender 和多个 Receiver<()>

还有建议给make this easier in the futures crate itself