TCP三次握手
三次握手就是建立TCP连接时,需要客户端和服务器共发送三个包
三次握手的主要作用是:确认双方的接受能力和发送能力正常,为可靠性的传输做准备
三次握手过程 | |
---|---|
客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN。此时客户端处于 SYN_SEND 状态。首部的同步位SYN=1,初始序号seq=x,SYN=1的报文段不能携带数据,但要消耗掉一个序号。 | 第一次握手 |
服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s)。同时会把客户端的 ISN + 1 作为ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_REVD 的状态。在确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y。 | 第二次握手 |
客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方已建立起了连接。 | 第三次握手 |
为什么一定要三次握手??
三次握手可以保证双方都具有接受和发送的能力
上面的为普遍回答,但是也是片面的
- 首先我们要弄明白什么是TCP连接?
用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括Socket、序列号和窗口大小称为连接。
所以,重要的是为什么三次握手才可以初始化Socket、序列号和窗口大小并建立 TCP 连接。
- 因为三次握手才可以阻止重复的历史连接的初始化
三次握手的首要原因是防止旧的重复连接初始化造成混乱
在错综复杂的网络中,谁也无法预知会出现什么情况,如果旧的报文先到达了服务端,那么服务端就会向客户端发送"syn+ack",来确认,客户端收到后可以自己判断这是一个旧的报文,就会发送RST给服务端,表示终止,如果为两次就不能判断是否为历史报文。 - 可以同步双方的初始序列号
当客户端发送SYN报文时,服务端回一个ACK确认,表示已经接收,那么服务端的SYN报文也要得到客户端的ACK回应,这样才能确保双方的初始序列号被可靠的同步。 - 可以避免资源浪费
两次握手会造成消息滞留的情况,即客户端在发送SYN报文后,因为网络堵塞没有收到ACK回应,就会重新发送SYN报文,那么服务器会重复的接受无用的SYN报文,造成资源的浪费。