一:过程
第一次(SYN):
客户端发送一个带有SYN标志的TCP报文段给服务器,设置SYN=1,并携带初始序列号Seq=x(随机值),进入SYN_SENT状态。等待服务器相应。
第二次(SYN+ACK):
服务器收到客户端发送的SYN报文段后,如果同意建立连接,会发送报文段给客户端:
设置SYN=1,携带服务器的初始序列号Seq=y(随机值)。
设置ACK=1,确认号Ack=x+1,表示已收到客户端的Seq=x。
服务器进入SYN_RVCD状态。
第三次(ACK):
客户端收到服务器发送的SYN+ACK报文段后,会发送报文段给服务器:
设置ACK=1,确认号Ack=y+1,表示已收到服务器的Seq=y。
序列号Seq=x+1,继续之前的序列。
客户端进入ESTABLISHED状态。
收到客户端的ACK后,服务器也进入ESTABLISHED状态,连接建立成功,可以开始进行数据传输。
二:为什么要3次?
1.确认双方都能发送和接收数据:
第一次握手确认客户端的发送能力和服务器的接受能力。
第二次握手确认服务器的发送能力和客户端的接受能力。
第三次握手确认客户端的发送能力和服务器的接受能力。
2.防止旧的连接请求误导对方:
通过三次握手,双方都能确认对方的状态是最新的,有效避免了网络中旧的、延迟的SYN包造成的错误连接。
3.防止重复数据包干扰:
三次握手确保双方都能有效处理重复的数据包,并建立一个唯一的连接。
三:为什么不是2次?
无法确认双向通信
TCP是全双工协议,需要确保客户端和服务器都能发送和接收数据。
两次握手过程:客户端->SYN->服务器 服务器->ACK->客户端
问题:
服务器发送ACK后,认为连接已建立,但客户端可能未收到ACK(比如网络丢包)。服务器无法确认客户端是否收到ACK。
后果:
服务器单方面认为连接成功,可能开始发送数据,而客户端未准备好,导致数据丢失。
无法同步服务器的序列号
TCP使用序列号确保数据按序传输。
两次握手中,服务器的ACK只确认了客户端的序列号(x),但未发送自己的序列号(y)。
问题:客户端无法知道服务器的初始序列号,后续数据传输可能因为序列号不同步而混乱。
后果:缺乏双向序列号同步,无法保证可靠传输。
无法防止旧连接干扰
网络中可能存在延迟的旧数据包,比如之前的SYN。
两次握手时:
客户端发送旧SYN,服务器收到后返回ACK。
服务器认为连接建立,但客户端未发送新连接。
问题:两次握手无法区分新旧连接,服务器可能误处理旧包。
后果:旧数据干扰新连接,导致不可靠性。
四:为什么不是四次握手?
四次也可以,但是多余,效率低。