【问题标题】:Assign port number manually for each connection为每个连接手动分配端口号
【发布时间】:2014-11-08 11:33:42
【问题描述】:

我正在运行一个服务器(比如在端口 50000 上)。任何新请求都会被接受,并且每次操作系统都会分配一个随机端口。我想手动分配端口号,而不是系统为我随机分配。

这样做的主要原因是我试图根据端口号做一些多播的事情。我打算在同一个端口上分配几个客户端。另一个端口上的下一个客户端插槽,依此类推。

有什么想法吗?

【问题讨论】:

  • 客户端打开连接时会得到一个随机的(源)端口,但服务器上的端口保持不变。如果你想让客户端连接到不同的端口,你需要监听多个端口。
  • 如果您连接到server:50000,那么您将始终连接到端口50000(所以这是固定的)。 otoh,clients 将有“随机”端口;如果您希望手动设置这些端口,则需要在客户端修复它们
  • 使用 bind() 将端口分配给套接字。
  • @vjcalling:当您在服务器端accept() 连接时,该连接被分配建立它的客户端 IP/端口和接受它的服务器端 IP/端口。没有什么是随机的。你把你的信息弄混了。
  • @vjcalling: 不,服务器不会将 random 端口分配给已接受的连接。它不能分配随机端口。阅读我的答案。服务器分配连接的客户端和服务器端正在使用的任何实际端口。只有客户端可以在连接到服务器之前为自己选择一个随机端口。客户端使用随机出站端口是正常和典型的行为。要改变这一点,您必须在调用 connect() 之前在客户端使用 bind()

标签: c++ linux sockets network-programming system-calls


【解决方案1】:

TCP 套接字由客户端 IP/端口和服务器端 IP/端口对的元组标识。服务器端 IP/端口由在 listen() 之前调用 bind() 决定。客户端 IP/端口通过在connect() 之前调用bind() 来明确决定,或者通过省略bind() 并让connect() 来隐式决定。当accept() 接受连接时,会为其分配建立该连接的客户端 IP/端口以及接受该连接的服务器端 IP/端口。

这里唯一可用的随机选项是在客户端。它可以调用connect() 而不使用前面的bind(),或者它可以调用bind() 并使用零IP/端口。在任何一种情况下,操作系统都会选择适当的网络适配器并分配其 IP(如果未明确说明),并分配一个随机可用的临时端口(如果未明确说明)。如果需要,调用 bind() 允许客户端分配这些值中的一个/两个。 bind() 在大多数情况下通常不在客户端使用,但在处理特定协议要求或防火墙/路由器问题时需要时允许使用。

仅通过端口跟踪客户是不够的。您需要改为跟踪完整的元组,或者至少跟踪元组的客户端 IP/端口对。来自同一网络的客户端将使用相同的客户端 IP 但不同的端口,但来自不同网络的客户端将使用不同的客户端 IP 并且可能使用相同的客户端端口,这完全没问题。所以单独使用端口可能会从错误的网络中找到错误的客户端。您还需要考虑客户端 IP。

当服务器接受连接时,服务器无法控制更改元组的值。操作系统需要这些值是可预测的,以便正确路由数据包。当您想向特定客户端发送数据包时,您需要知道客户端 IP 和端口。

如果您想在已接受连接的元组中使用不同的服务器端 IP/端口值,唯一的选择是打开多个与所需服务器端值绑定的侦听套接字。

【讨论】:

  • +1 但“服务器无法控制更改元组的值”和“操作系统需要这些值是可预测的”,因为这就是 RFC 793 中所说的:指定第二个端口号的 TCP 握手。
猜你喜欢
  • 1970-01-01
  • 2015-08-03
  • 1970-01-01
  • 2015-08-15
  • 1970-01-01
  • 2015-10-13
  • 2021-04-26
  • 1970-01-01
  • 2013-11-27
相关资源
最近更新 更多