【问题标题】:Should/can a client use the same port to bind to multiple servers客户端应该/可以使用相同的端口绑定到多个服务器
【发布时间】:2013-09-03 01:19:52
【问题描述】:

假设我有一个客户端通过 TCP 连接到一堆主机上的 1000 个不同的服务器。然后我想在同一台主机上启动 100 个客户端。我通常会用完临时端口(由操作系统分配)。我的解决方案是让每个客户端在连接到所有 1000 个服务器时绑定到 1 个端口(因此只使用 100 个端口)。

我的问题是 - 这应该是我默认做的事情吗?换句话说,在我构建的自定义连接层中,客户端是否应该自动重用相同的端口来连接到多个服务器(因此更具可扩展性),还是这种方法有缺点?我正在使用 Linux。

更新:原来我的解决方案依赖于SO_REUSEPORT 的可用性。 SO_REUSEPORT 的主要用例是用于负载平衡侦听套接字,其中多个线程/进程用于管理传入连接,但我看不出它不能用于绑定到同一端口的 TCP 客户端的任何原因在连接之前。 Linux kernel 3.9 now supports this。使用 python 3.3.2 和 Linux 3.11.0,以下工作:

from socket import *

s1 = socket(AF_INET, SOCK_STREAM)
s1.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
s1.bind(('localhost', 23456))

s2 = socket(AF_INET, SOCK_STREAM)
s2.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
s2.bind(('localhost', 23456))

正如@glglgl 建议的那样,它会尽可能晚地失败,如果您尝试连接到同一个远程(host, port),您会收到一条错误消息:

OSError: [Errno 99] Cannot assign requested address

我看不出有什么理由不能将它用于解决可伸缩性问题,因为许多进程通过 TCP 连接到许多其他进程,我很想听听任何 cmets 关于我为什么应该t 只是在我的连接层客户端中构建,默认情况下重用相同的端口。

【问题讨论】:

  • @EJP 请在上面查看我的更新 - 如果您在这里有任何建议,我很想听听您的想法。
  • 您编辑中的 Linux 功能似乎针对的是服务器,而不是客户端。你真的需要几万个出站连接,就够用完端口空间了吗?

标签: linux sockets tcp


【解决方案1】:

默认情况下客户端是否应该使用同一个套接字绑定到多个服务器

不,因为客户端不能使用相同的套接字绑定到多个服务器,默认情况下或任何其他方式。你的意思是'使用相同的端口?'

假设我有一个客户端通过 TCP 连接到一堆主机上的 1000 个不同的服务器。然后我想在同一台主机上启动 100 个客户端。我通常会用完临时端口(由操作系统分配)。

换句话说,您确实是指“相同的端口”,而不是“相同的套接字”。

我的解决方案是让每个客户端在连接到所有 1000 个服务器时绑定到 1 个端口(因此只使用 100 个端口)。

但是您的“解决方案”不起作用。操作系统不允许您为多个同时出站连接重用同一个本地端口。

我的问题是 - 这应该是我默认做的事情吗?

你根本做不到,更别提by default了。

【讨论】:

  • 我想知道为什么这不起作用。鉴于 TCP 连接是由(local IP, local port, remote IP, remote port) 定义的,只要我连接到不同的主机,能够将多个传出套接字绑定到同一个本地端口应该不会有什么害处。 (如果我做了一些不想要的事情,他们可能会在那时伤害我,而不是过早地。)
  • -1,这就是SO_REUSEADDRSO_REUSEPORT 的意义所在。
  • @glglgl 它不起作用,因为在 Sockets API 中,bind() 在 connect() 之前,所以内核不知道你要连接到不同的 IP 地址/端口当您执行绑定()时。如果有一个原子绑定/连接 API,内核将能够实现完整的 TCP 规范并允许它。但是没有,所以不能。
  • @EJP 是的,我的意思是使用相同的端口,而不是套接字——显然每个连接都需要自己的套接字。我解决了这个问题。
  • @EJP 它可以bind() 成功的方式实现,但如果无法组合,connect() 将失败。 IOW,如果仍然有可能成功,则尽可能晚地失败。唉,还没有。
猜你喜欢
  • 2019-07-12
  • 1970-01-01
  • 2021-10-10
  • 2011-10-14
  • 1970-01-01
  • 2011-12-09
  • 2015-10-15
  • 1970-01-01
  • 2013-05-27
相关资源
最近更新 更多