这两个数据包是否属于同一个 tcp 套接字?

网络工程 通讯协议 网络 协议理论 传输协议
2021-07-07 05:14:01

假设我们有两个数据包AB

A: 有源IP S1、目的IP D1、源端口SP1、目的端口DP1

B: 有源IP S2、目的IP D1、源端口SP2、目的端口DP1

两者都是TCP。这两个数据包现在有相同的套接字吗?


关于 UDP 我读过它的套接字由目标 IP 和目标端口号组成。Soo 如果这是用 UDP 完成的,那么两个数据包都会被同一个套接字接收。

但是这个例子是针对 TCP 的,在这里我不确定它是否也会通过 TCP 的相同套接字?

3个回答

首先,TCP 不关心单个数据包。如果这些只是没有任何先前连接建立的数据包,那么它们将被简单地丢弃,不涉及套接字。所以我假设这是关于已建立的连接,或者是建立连接的初始数据包。TCP连接至少由 (src-ip, src-port, dst-ip, dst-port) 的 4 元组定义。由于这 4 个元组在两种情况下明显不同,因此需要不同的套接字。

关于 UDP 我读过它的套接字由目标 IP 和目标端口号组成。

这仅适用于未连接的UDP 套接字。随着连接的UDP套接字再次4元组是相关的。

关于 UDP 我读过...

TCP 和 UDP 的主要区别在于 TCP 是面向连接的,而 UDP 用于传输单个数据包。

UDP 套接字正在处理到达计算机上某个(目标)端口的所有 UDP 数据包。

TCP 套接字正在处理属于某个 TCP 连接的所有数据包。

这两个数据包现在有相同的套接字吗?

它比你想象的要复杂:

您描述的情况通常发生在“服务器端”(在使用accept()API 处理传入连接的计算机上- 例如 Web 服务器)。

假设两台计算机(运行 Web 浏览器)想要连接到同一个 Web 服务器。两台计算机都选择了相同的“源 TCP 端口”。此时两台计算机发送到web服务器的数据包满足你的条件:两台计算机发送的数据包只有源IP地址不同,目的IP地址、目的端口和源端口相同。

但是,在“服务器端” ,处理单个 TCP 连接涉及两个套接字

  1. 一个使用listen()accept()等待传入 TCP 连接的套接字
  2. 对于每个传入的 TCP 连接,由 返回一个套接字accept()

当 TCP 数据包是TCP 连接第一个数据包时,该数据包由listen()在目标端口上执行 a 的 TCP 套接字“处理”

这个套接字不关心源 IP 地址,也不关心源 TCP 端口——就像 UDP 套接字一样。套接字正在处理具有特定目标 IP 地址和特定目标端口的 TCP 连接的所有第一个数据包。

当收到第一个数据包时,access()API创建并返回第二个套接字(处理 TCP 连接)

该套接字处理某个连接(因此处理 TCP 连接的所有其他数据包)。

因为我们在示例中有两个不同的连接,两台计算机使用相同的“源 TCP 端口”连接到同一台服务器,所以两个不同的套接字将处理仅目标 TCP 端口不同的数据包。

这取决于您使用谁的套接字定义,以及在某些情况下数据包是打开新连接还是为现有连接传输数据。

定义 TCP 的 RFC 将术语套接字定义为 IP 地址和端口的组合。根据这个定义,两个数据包在服务器端具有相同的套接字,但在客户端具有不同的套接字。

然而,“sockets API”* 不使用这个定义。套接字 API 使用术语套接字来指代操作系统提供给应用程序的通信对象。为了避免本文其余部分的混淆,我将使用术语“套接字对象”来指代套接字 API 调用的套接字。

当您启动服务器时,它会创建一个套接字对象,将其绑定到所需的本地地址/端口并告诉操作系统开始列出连接。指定的地址可能是单个本地地址,也可能是用于侦听所有本地地址的通配符(关于 IPv6 有一些微妙之处,我不会在这里介绍)。这个套接字对象的远程地址和端口字段是通配符,允许它接受来自任何地方的连接请求。

当服务器接受连接时,操作系统会创建一个新的套接字对象来表示新连接。此套接字对象填充了完整的地址和端口字段。

* 有时称为 Berkeley 套接字或 Posix 套接字。这个 API 起源于 BSD,由 posix 标准化。此 API 或其变体用于所有主要操作系统上的 IP 通信。