假设我们有两个数据包A
和B
。
A
: 有源IP S1
、目的IP D1
、源端口SP1
、目的端口DP1
B
: 有源IP S2
、目的IP D1
、源端口SP2
、目的端口DP1
两者都是TCP。这两个数据包现在有相同的套接字吗?
关于 UDP 我读过它的套接字由目标 IP 和目标端口号组成。Soo 如果这是用 UDP 完成的,那么两个数据包都会被同一个套接字接收。
但是这个例子是针对 TCP 的,在这里我不确定它是否也会通过 TCP 的相同套接字?
假设我们有两个数据包A
和B
。
A
: 有源IP S1
、目的IP D1
、源端口SP1
、目的端口DP1
B
: 有源IP S2
、目的IP D1
、源端口SP2
、目的端口DP1
两者都是TCP。这两个数据包现在有相同的套接字吗?
关于 UDP 我读过它的套接字由目标 IP 和目标端口号组成。Soo 如果这是用 UDP 完成的,那么两个数据包都会被同一个套接字接收。
但是这个例子是针对 TCP 的,在这里我不确定它是否也会通过 TCP 的相同套接字?
首先,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 连接涉及两个套接字:
listen()
并accept()
等待传入 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 通信。