【问题标题】:How does a client know which port to send data after accept()客户端如何知道accept()后发送数据的端口
【发布时间】:2022-01-20 22:48:22
【问题描述】:

假设我们有一个可以接受多个客户端的服务器。首先,它必须创建一个套接字,然后将它与一个端口和一个 IP 绑定,最后监听来自客户端的连接请求。在accept()与客户端建立连接后,服务器会创建一个新套接字来与特定客户端进行通信。我的问题是客户端是否会将其数据发送到它发送初始请求的同一端口,如果不是,它如何知道将其发送到哪里?

【问题讨论】:

  • 可能与它发送连接请求的端口相同。
  • 您可以使用例如getsockname 获取套接字的本地详细信息,例如其端口号。
  • 还请记住,端点由三件事定义:地址、协议和端口号。连接由两个端点定义。这意味着一个端点可以在不同的连接之间“共享”,因为连接的另一端唯一地定义了连接本身。
  • @Someprogrammerdude 如果我说得对,你是说可能有多个连接与一个端口相关联,并且每个服务器客户端都可以通过确保这对(客户端和自身)包含一个自己的客户端。但是既然那个端口有一个监听套接字,为什么它不尝试从已经连接到服务器的客户端接收数据呢?它如何知道他们的数据是用于另一个服务器进程的?
  • 通过连接发送的每个数据包都包含其源和目标三元组(地址、协议、端口)。然后系统可以使用源和目标三元组作为唯一连接。然后它使用目标三元组来了解本地系统上的哪个“程序”将数据包发送到,并使用源三元组将数据包放入正确的队列中。

标签: c sockets


【解决方案1】:

套接字连接由[Protocol, Local IP, Local Port, Peer IP, Peer Port] 的元组唯一标识。

TCP 服务器创建一个带有[TCP, Listen IP, Listen Port, 0, 0] 元组的监听 套接字。当客户端请求连接到服务器时,网络会将请求路由到指定的 IP/端口。然后接收设备将请求路由到匹配的侦听套接字,与客户端执行 3 次握手,并将其放入队列中。稍后,当调用accept() 时,它会从队列中提取下一个挂起的客户端,并返回一个用[TCP, Listen IP, Listen Port, Client IP, Client Port] 元组标识的新套接字。因此,单个侦听套接字可以接受来自不同客户端 IP/端口组合的多个客户端。

TCP 客户端创建一个带有[TCP, Local IP, Local Port, 0, 0] 元组的正在连接 套接字。 3way 握手完成后,套接字的元组更新为[TCP, Local IP, Local Port, Server IP, Server Port]。因此,客户端可以将不同的套接字连接到具有不同服务器 IP/端口组合的不同服务器。

所有后续数据交换都使用这些元组。

从客户端的连接套接字发出的数据将被发送到关联的服务器 IP/端口,并存储在接受的服务器套接字的缓冲区中,其元组与客户端和服务器都匹配。

从服务器的监听套接字发出的数据将被忽略,因为没有关联的客户端。

从接受的服务器套接字发出的数据将被发送到关联的客户端 IP/端口,并存储在连接的客户端套接字的缓冲区中,其元组与客户端和服务器匹配。

【讨论】:

  • 是的!这是最有意义的!感谢您的宝贵时间!
【解决方案2】:

一般情况下,每种通信都有一个默认端口分配。操作系统可以保持打开或关闭,可以检查。

假设对于 FTP 连接,为握手分配了一个单独的端口,无论请求多少新的 FTP 连接,所有新连接都将转到同一个端口,一旦握手完成,数据交换就完成了通过另一个端口,即使我们没有指定端口。如果网络管理器之前有端口列表条目,它将请求相同的端口。

SSH 示例 如果您要求

ssh -X <IP> 

即使您没有提及 port ,您的系统也知道要请求哪个端口,并且在服务器端总是有一些开放的端口将侦听您的请求,并且根据您在握手时发送的数据,它将继续侦听或屏蔽你。

奖励是您可以在服务器端打开您的自定义端口,该端口将监听您的请求。 TCP 实现默认声明哪个端口将用于哪种通信。

【讨论】:

  • OP 询问接受后会发生什么。在这里提到 FTP 数据连接使用不同的端口是令人困惑的,因为这不再是原始的接受,但数据连接由不同的侦听器 + 接受处理。而对于这一个端口保持不变。
  • 服务器接受请求后,通过其他端口向客户端端口发起数据传输。由于服务器已经通过 SYN 数据包知道客户端 IP 和端口(TCP 连接的开始)[可以看到 wireshark 应用程序]。每个 TCP 数据包都包含 [源 ip,目标 ip,源和目标端口和协议,....)一个服务器确认第一个数据包通信,双方现在互相认识,除非任何信息发生变化[源 IP,目标 IP ,源端口,目标端口] 。 techtarget.com/searchnetworking/definition/port-number
【解决方案3】:

客户端使用源 IP 和端口连接到具有目标 IP 和端口的服务器。双方接受完全相同的IP和端口后,继续用于数据交换,以建立连接。

【讨论】:

  • 监听套接字如何知道不再尝试接受已经接受的客户端?数据包的消息是否不同?服务器端是否有某种类型的历史记录/缓存?
  • @BillTheKid 也许您可能需要多花一点时间了解 TCP 以及它如何处理连接。例如了解什么是三次握手
  • @Someprogrammerdude 哦,那好吧!我们的谈话真的很有用!谢谢你的时间!
猜你喜欢
  • 2017-02-12
  • 2017-01-12
  • 2021-07-04
  • 2018-08-02
  • 1970-01-01
  • 2013-04-27
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多