当客户端的 IP 更改时,TCP 会话会发生什么?
我做了一个简单的测试,让 netcat 监听一个端口,并从客户端机器连接到该端口。然后我在 nc 会话打开并发送了一些数据时更改了客户端的 IP,更改 IP 后服务器没有收到任何数据。
- 我知道它们是不同的层,但是 TCP 是否使用 IP 来区分会话?
- 我的示例是否因为应用程序如何处理它而不起作用,或者这是否因为 TCP/IP/以太网层发生的事情而不起作用?
- 这是否取决于操作系统的实现?(我目前对Linux最感兴趣)
当客户端的 IP 更改时,TCP 会话会发生什么?
我做了一个简单的测试,让 netcat 监听一个端口,并从客户端机器连接到该端口。然后我在 nc 会话打开并发送了一些数据时更改了客户端的 IP,更改 IP 后服务器没有收到任何数据。
我的理解是 TCP 套接字由 IP + 端口号组成,因此更改 IP 会中断该连接。nc 无法知道 IP 改变了,所以它继续向原始 IP 发送数据,直到会话超时。
请参阅RFC 793(传输控制协议),特别是第 2.7 节:
2.7. 连接建立和清除
为了识别 TCP 可以处理的单独数据流,TCP 提供了一个端口标识符。由于端口标识符由每个 TCP 独立选择,它们可能不是唯一的。为了在每个 TCP 中提供唯一地址,我们将标识 TCP 的 Internet 地址与端口标识符连接起来,以创建一个套接字,该套接字在连接在一起的所有网络中都是唯一的。
我建议使用 Wireshark 或其他数据包嗅探器来亲自观察流量并查看它的运行情况。
前面的答案会告诉你,当 IP 地址发生变化时,TCP 连接无法保持活动状态。这在 2009 年是正确的,当时写了这些答案。
然而,在 2013 年 1 月发布了RFC 6824,它引入了一种在 IP 地址更改时保持 TCP 连接活动的方法。截至 2014 年 6 月,它尚未得到广泛支持。最值得注意的是,参考实现作为 Linux 补丁存在,iOS7 默认支持 MPTCP。维基百科一共列出了五个实现。
会话将终止。TCP 套接字是 dst 端口、dst ip、src 端口、src ip。如果其中任何一项发生变化,则应断开连接(至少,根据 Stevens 的说法)。
编辑:任何符合 RFC 的实现都是如此。RFC 793,第 2.7 节
其他人则从IP + Port对识别连接的角度进行了回答。让我谈谈它在分层结构中是如何工作的。
TCP 是一个在不可靠的数据包层 (IP) 之上提供可靠流“幻觉”的层。为此,它必须考虑几个变量来管理流,并且还必须为下面的层提供相关参数。
所以,当你要求 TCP 打开一个流时,你给它目标的 IP+端口。它保留该 IP 编号,并且每次必须传输某些内容时,它都会组装一个 IP 数据包并告诉 IP 层将其发送到仅由原始 IP 编号标识的预期机器。
当你改变了一台机器的 IP 号时,另一台的 TCP 层没有任何办法知道发生了什么。它只看到发送到原始 IP 号的任何 IP 数据包都不再得到应答(可能它会收到一条 ICMP 消息,告知没有具有该 IP 号的机器)。此外,它不会再收到具有该 IP 号的数据包。显然,连接将在超时后断开。
更糟糕的是,它可能会开始从不同的来源(新的 IP 号)获取一些不相关的数据包,但这些数据包假设连接已经到位!当然,机器可能得到的唯一答案(如果有的话)是一个 RST 数据包,以使其立即停止并停止。
TCP 会话由连接两端的 ip 地址和端口号标识。更改一侧的 IP 地址会中断该会话。
(源地址、源端口、目的地址、目的端口)组合称为套接字对。TCP 堆栈使用它来识别连接。一旦建立,TCP 就无法更新其中的任何一个。
SCTP允许端点动态更改其地址,但尚未广泛部署(无论如何尚未)。