之前在春招面试的时候,经常问到,但是答得无非都是保证可靠性之类的,理解不透彻。
什么是 TCP 连接:
接下来以三个⽅⾯分析三次握⼿的原因:
- 三次握⼿才可以阻⽌重复历史连接的初始化(主要原因)
- 三次握⼿才可以同步双⽅的初始序列号
- 三次握⼿才可以避免资源浪费
简单来说,三次握手的首要原因是为了防⽌旧的重复连接初始化造成混乱。
⽹络环境是错综复杂的,往往并不是如我们期望的⼀样,先发送的数据包,就先到达⽬标主机,可能会由于⽹络拥堵等乱七⼋糟的原因,会使得旧的数据包,先到达⽬标主机。
三次握手情况下
客户端连续发送多次 SYN 建⽴连接的报⽂,在⽹络拥堵情况下:
两次握手情况下
如果是两次握⼿连接,就不能判断当前连接是否是历史连接,三次握⼿则可以在客户端(发送⽅)准备发送第三次报⽂时,客户端因有⾜够的上下⽂来判断当前连接是否是历史连接:
所以,TCP 使⽤三次握⼿建⽴连接的最主要原因是防止历史连接初始化了连接。
TCP 协议的通信双方, 都必须维护⼀个「序列号」,序列号是可靠传输的⼀个关键因素,序列号的作⽤:
可⻅,序列号在 TCP 连接中占据着⾮常᯿要的作⽤,所以当客户端发送携带「初始序列号」的 SYN 报⽂的时候,需要服务端回⼀个 ACK 应答报⽂,表示客户端的 SYN 报⽂已被服务端成功接收,那当服务端发送「初始序列号」给客户端的时候,依然也要得到客户端的应答回应,这样⼀来⼀回,才能确保双⽅的初始序列号能被可靠的同步。
四次握⼿其实也能够可靠的同步双⽅的初始化序号,但由于第⼆步和第三步可以优化成⼀步,所以就成了「三次握⼿」。
⽽两次握⼿只保证了⼀⽅的初始序列号能被对⽅成功接收,没办法保证双⽅的初始序列号都能被确认接收。
如果只有「两次握⼿」,当客户端的 SYN 请求连接在⽹络中阻塞,客户端没有接收到 ACK 报⽂,就会重新发送 SYN ,由于没有第三次握⼿,服务器不清楚客户端是否收到了⾃⼰发送的建⽴连接的 ACK 确认信号,所以每收到⼀个 SYN 就只能先主动建⽴⼀个连接,这会造成什么情况呢?
如果客户端的 SYN 阻塞了,重复发送多次 SYN 报⽂,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。
即两次握⼿会造成消息滞留情况下,服务器重复接受⽆⽤的连接请求 SYN 报⽂,⽽造成重复复分配资源。
TCP 建立连接时,通过三次握⼿能防⽌历史连接的建⽴,能减少双⽅不必要的资源开销,能帮助双⽅同步初始化序列号。序列号能够保证数据包不᯿复、不丢弃和按序传输。
不使⽤「两次握⼿」和「四次握⼿」的原因:
整理自小林coding所著的《图解网络》,侵删