如何为多个使用者重用服务器端TCP端点?

时间:2017-04-21 06:31:55

标签: tcp websocket rust

我是一个尝试理解TCP的初学者,我正在使用Rust。如果我创建一个新的侦听器并将其绑定到一个地址

let tcplistener = TcpListener::bind("127.0.0.1:55555").unwrap();

我可以tcplistener.accept() 127.0.0.1:55555与客户端上的其他端点之间的新连接。

就我而言,tcplistener位于表示插件的结构的实例中。每个插件都应该可以从自己的浏览器选项卡中控制。每个插件有一个连接(端点对),其中一个端点始终为127.0.0.1:55555。插件在单个线程中运行,具有非阻塞侦听器和流。我使用websockets,但我不确定这个问题是否特定于websockets。

我现在正在做的是

  • 实例化插件A
  • 接受从浏览器标签到插件A的第一个连接
  • 之后,将插件A中的tcplistener字段分配给具有任意OS分配端口的新创建的侦听器

这似乎有效;如果我之后实例化了一个新的插件B,我可以创建一个绑定到127.0.0.1:55555并接受连接的侦听器。如果我没有创建一个具有不同地址/端口的新监听器,那么我得到的#34;地址已经在使用"错误。

这显然不是一个好的解决方案,因为它无缘无故地占用了所有其他端口。有更好的方法吗?

评论说:

  

为什么每个插件都有TcpListener?为什么没有一个组件与监听器,调用accept,然后将返回的TcpStream交给每个构建的插件?

这听起来不错,但是TcpListener会在哪里存储,以及它如何传递流?我看到存储的可能性:

  • 主持人。我无法修改插件主机,我只是一个插件作者。
  • 一个专用插件。我看到的问题是插件无法访问存储在另一个插件中的任何信息,所以我不知道该怎么做。
  • 单独运行的过程。我可以想象单独运行服务器并让插件成为客户端。用户可以将他们的浏览器连接到服务器,服务器以某种方式代理插件。听起来很合理,但这里的不便之处在于插件用户必须将服务器安装为单独的包。所以我真的很想避免这种情况。虽然我认为启动服务器可以在插件实例化时自动完成,但这可能是最佳选择吗?

1 个答案:

答案 0 :(得分:1)

如果我正确理解您的所有限制,一种解决方法是使用OptionOption用于“某事或某事物”的情况。

在这里,您可以拥有Option<TcpListener>。在新初始化的插件上,这将设置为Some(...),一旦被接受,将转换为None

这确实有许多缺点:

  • 有一段时间没有听众。
  • 你必须处理听众None的可能性。
  • 在第一个插件接受之前,你无法启动第二个插件。

如果看似合理,某种亲子关系可能更好,甚至限制为单身插件。