服务器如何找出要发送到哪个客户端端口?

Sub*_*esh 29 tcp socket

据我了解,这是客户端发出连接请求时发生的情况:

  1. 服务器将绑定到特定的端口号。端口号始终绑定到侦听进程。由于只有服务器在监听传入的连接,我们不需要在客户端绑定
  2. 服务器将继续监听该端口号。
  3. 客户端将发送connect()请求。
  4. 服务器将使用accept(). 一旦服务器接受客户端的请求,内核分配服务器进一步随机端口号send()receive(),因为不能用于发送和监听服务器上的相同的端口号,和先前端口仍然是监听新连接

鉴于所有这些,服务器如何找出客户端正在接收的端口?我知道客户端将发送带有源端口和目标端口的 TCP 段,因此服务器将使用该段的源端口作为其目标端口,但是服务器调用什么函数来查找该端口?是accept()吗?

der*_*ert 35

它是数据包中 TCP(或 UDP 等)标头的一部分。所以服务器发现是因为客户端告诉了它。这类似于它如何找出客户端的 IP 地址(它是 IP 标头的一部分)。

例如,每个 TCP 数据包都包含一个 IP 标头(至少包含源 IP、目标 IP 和协议 [TCP])。然后是一个 TCP 标头(带有源端口和目标端口,以及更多)。

当内核接收到远程 IP 为 10.11.12.13(在 IP 头中)和远程端口为 12345(在 TCP 头中)的 SYN 数据包(TCP 连接的开始)时,它就知道远程 IP 和端口. 它发回一个 SYN|ACK。如果它得到一个 ACK​​ 返回,listen调用将返回一个新的套接字,为该连接设置。

TCP 套接字由四个值(远程 IP、本地 IP、远程端口、本地端口)唯一标识。您可以有多个连接/套接字,只要其中至少一个不同。

通常,到服务器进程的所有连接的本地端口和本地 IP 都是相同的(例如,所有到 sshd 的连接都在 local-ip:22 上)。如果一台远程机器建立多个连接,每个连接将使用不同的远程端口。因此,除了远程端口之外的所有内容都将相同,但这很好——四个中只有一个必须不同。

您可以使用例如wirehsark 来查看数据包,它会为您标记所有数据。这是突出显示的源端口(注意它在解码数据包中突出显示,以及底部的十六进制转储):

Wireshark 显示 TCP SYN 数据包