1081 字
5 分钟
为什么要三次握手
为什么要三次握手
-
答题思路:
- 最基础的一点👉收发能力
- 细化的三点:
- 阻止重复历史连接的初始化(重要)👉举例子介绍
- 同步双方的初始化序列号
- 避免浪费资源
-
最基础的一点:
- 三次握手才能确定双方的收发能力是否正常
- 只有两次握手👉
-
从三方面详细分析需要三次握手的原因:
- 三次握手才可以阻止重复历史连接的初始化(主要原因)
- 三次握手才可以同步双方的初始序列号
- 三次握手才可以避免资源浪费
-
原因一:避免历史连接(相同ISN):
- 防止旧的重复连接初始化造成混乱
- 我们考虑一个场景:
- 客户端先发送了SYN(seq=90)报文,然后客户端宕机了,而且这个SYN报文还被网络阻塞了,服务端并没有收到,接着客户端重启后,又重新向服务端建立连接,发送了SYN(seq=10O)报文
- ==(注意!不是重传SYN,重传的SYN的序列号是一样的)。==
- 客户端先发送了SYN(seq=90)报文,然后客户端宕机了,而且这个SYN报文还被网络阻塞了,服务端并没有收到,接着客户端重启后,又重新向服务端建立连接,发送了SYN(seq=10O)报文
- 客户端连续发送多次SYN(都是同一个四元组)建立连接的报文,在网络拥堵情况下:
- 一个「I旧SYN报文」比「最新的SYN」报文早到达了服务端,那么此时服务端就会回一个SYN+ACK报文给客户端,此报文中的确认号是91(90+1)
- 客户端收到后,发现自己期望收到的确认号应该是100+1,而不是90+1,于是就会回RST报文
- 服务端收到RST报文后,就会释放连接
- 后续最新的SYN抵达了服务端后,客户端与服务端就可以正常的完成三次握手了
- 上述中的「旧SYN报文」称为历史连接,TCP使用三次握手建立连接的最主要原因就是:
- 防止「历史连接」初始化了连接
-
原因二:同步双方初始序列号:
- TCP 协议的通信双方, 都必须==维护同一个「序列号」==, 序列号是可靠传输的一个关键因素,它的作用:
- 接收方可以去除重复的数据
- 接收方可以根据数据包的序列号按序接收
- 可以标识发送出去的数据包中, 哪些是已经被对方收到的(通过 ACK 报文中的序列号知道)
- 可见,序列号在 TCP 连接中占据着非常重要的作用,所以当客户端发送携带「初始序列号」的 SYN 报文的时候,需要服务端回一个 ACK 应答报文,表示客户端的 SYN 报文已被服务端成功接收,那当服务端发送「初始序列号」给客户端的时候,依然也要得到客户端的应答回应,这样一来一回,才能确保:
- ==双方的初始序列号能被可靠的同步==
- 四次握手其实也能够可靠的同步双方的初始化序号,但由于第二步和第三步可以优化成一步,所以就成了「三次握手」
- 而两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收
- TCP 协议的通信双方, 都必须==维护同一个「序列号」==, 序列号是可靠传输的一个关键因素,它的作用:
-
原因三:避免资源浪费(不同ISN):
- 如果只有「两次握手」,当客户端发生的 SYN 报文在网络中阻塞,客户端没有接收到 ACK 报文,就会重新发送 SYN
- 由于没有第三次握手,服务端不清楚客户端是否收到了自己回复的 ACK 报文,所以服务端每收到一个 SYN 就只能先主动建立一个连接,这会造成什么情况呢?
- 如果客户端发送的 SYN 报文在网络中阻塞了,重复发送多次 SYN 报文,那么服务端在收到请求后就会==建立多个冗余的无效链接==,造成不必要的资源浪费。
- 即两次握手会造成消息滞留情况下,服务端重复接受无用的连接请求 SYN 报文,建立连接后,服务器等待数据,客户端却处于关闭状态,浪费服务器资源
确认收发能力