TCP--- 为什么三次握手,四次挥手?

本贴最后更新于 1240 天前,其中的信息可能已经事过景迁

后文有个术语叫做 MSL,这儿先解释一下。

MSL 全称叫做 Maximum Segment Lifetime 即最大报文生存时间,它是一个数值,表示了一个报文在整个网络中最多能存活多久,防止消息一直在网络中驻留。

Linux 系统可以使用 cat /proc/sys/net/ipv4/tcp_fin_timeout 查看其值,一般是 60 或者 120

后文还有个术语叫做四元组,其实就是 TCP 报文的 源IP目的IP源端口目的端口,在 TCP 交互中只要发现四元组是相同的,那么就会认为是属于同一条 TCP 连接中的数据

三次握手

image.png

why?

需要三次握手而不是两次握手可以通过一个例子知道缘由:

假设通过两次握手就能建立连接,那么可能会出现这么一种情况。

客户端A向服务端发送SYN报文,请求建立连接

服务端B收到了这个SYN报文,并且也向A发送ACK报文,这时候服务端就进入了连接建立状态,于是开始等待客户端A说话发消息

but,很不幸的是,服务端B收到A发来的SYN报文其实是很久之前的消息,可能是因为信道堵塞或者其他奇奇怪怪的原因,导致这个SYN报文姗姗来迟。服务端就永远也等不到客户端的下文了

在教材《计算机网络》中的表述是:

采用三次握手是为了防止已失效的连接请求又传送到服务器端,因而产生错误

但其实不太准确,还有如下理由:

为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤

如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认

题外话

在服务端进入 SYN_RECD 状态之后,收到客户端最后一个 ACK 之前,这个时候的连接称之为半连接,服务端会使用一个队列来存储这些半连接

如果客户端搞事情,在短时间内伪造大量不存在的 IP 地址,向服务器不断地发送 SYN 包,服务器回复确认包,并等待客户的确认。由于源地址是不存在的,服务器需要不断的重发直至超时,这些客户端伪造的 SYN 包将长时间占用未连接队列,正常的 SYN 请求被丢弃,而且还会导致服务端半连接队列被撑爆,无法就收新的半连接,也就更无法建立新的 TCP 连接

四次挥手

image.png

四次挥手而不是三次挥手的原因:

需要给被动断开连接的一方留出一段时间,以便它处理完最后的数据。在图中就是指的 CLOSE_WAITLAST_ACK 之间的时间

那么还有一个问题,为什么主动断开方还需要一个 TIME_WAIT 状态,并且等待 2MSL 时间后才真正的断开连接呢?
为了便于描述,我们设想这么一个处于拆链 也就是断开TCP连接的过程

这个连接的两端分别是A和B,A是主动发起断开请求的一方。
A刚发送完最后一个ACK报文,进入到了TIME_WAIT状态,
B此时处于LAST_ACK状态,等待A的最后一个ACK报文到来。
随着时间的推移,接下来A发送给B的ACK有两种结局:
1.ACK报文在网络中丢失。这种情况我们不需要关注,因为有重传机制
2.B接受到ACK报文。
    我们假设A发送了ACK报文后过了一段时间t之后B才收到该ACK,则肯定有 0 < t <= MSL。
    因为A并不知道它发送出去的ACK要多久对方才能收到,所以A至少要维持MSL时长的TIME_WAIT状态才能保证它的ACK从网络中消失。同时处于LAST_ACK状态的B因为收到了ACK,所以它直接就进入了CLOSED状态,而不会向网络发送任何报文。
    所以晃眼一看,A只需要等待1个MSL就够了,but仔细想一下其实1个MSL是不行的,因为在B收到ACK前的一刹那,B可能因为没收到ACK而重传了一个FIN报文,这个FIN报文要从网络中消失最多还需要一个MSL时长,
    所以A还需要多等一个MSL

简单粗暴的说,最后等待 2MSL 时间就是为了以静默的方式 吃掉 对方的数据,避免对后续的连接造成影响

什么情况下会对后续连接造成影响呢?

假设 A 端并没有等待 2MSL 这个操作,直接关掉了连接,B 端也关掉了连接。恰好 B 端有一个报文 xxx 因为信道堵塞,在 A 端关闭连接后还存在,没有被 A 端静默吃掉。

啪的一下,很快啊,B 端又重新建立了一个连接,并且其四元组还和上一次的相同,那么之前的那个报文 xxx 慢悠悠的到达了 A 端后,A 端会认为是这次新 TCP 连接中的消息。。这不就搞出脏数据了嘛

参考

知乎

看官大爷们觉得如何

单选 公开 永不结束 4 票
我觉得 ok
25% 1 票
我觉得 ok
50% 2 票
我觉得 ok
25% 1 票

打赏 10 积分后可见
10 积分 • 1 打赏
  • TCP
    30 引用 • 38 回帖 • 2 关注
  • 协议
    4 引用 • 1 回帖 • 1 关注
  • 网络
    128 引用 • 177 回帖 • 3 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • someone1764 1

    没别的意思,就是想发个表情

    1 操作
    someone1764 在 2020-11-27 09:40:03 更新了该回帖