为什么需要三次握手
流程
三次握手流程如下,将发起连接的称为客户端,被连接方称为服务端。
客户端发送SYN报文,SYN位置1,且有ISN初始号作为序列号SEQ1。
服务端发送SYN_ACK报文,SYN和ACK位均置1,且有ISN初始号作为序列号SEQ2,ACKNO为SEQ1 + 1
客户端发送ACK报文,ACK位置1,且ACKNO为SEQ2 + 1
角度1:确认连接双方能力
参考链接
目的:双方均确认双方具有发送能力和接收能力。
客户端发送SYN报文并被服务端接收:此时服务端确认客户端有发送能力,服务端有接收能力。
服务端发送SYN_ACK报文并被客户端接收:自己发送的SYN报文被收到,确认自己发送能力和服务端的接收能力;能收到服务端的SYN_ACK报文,确认自己的接收能力和服务端的发送能力。因此第2次握手结束时,客户端就确认4个能力均具备了。
客户端发送ACK报文并被服务端接收:客户端收到了SYN_ACK报文,确认客户端具有接收能力和自己的发送能力。
第三次握手原因:如果没有第3次握手,则服务端无法确认本身的发送能力和客户端的接收能力。可能客户端根本无法接收。若在此时建立连接,则会造成资源浪费,发送报文也无法得到回应。
角度2:避免半连接
参考链接
TCP报文中均携带了确认号,若客户端因为网络拥塞,SYN报文很长时间才到达服务端,则客户端会超时重传SYN报文。然后客户端和服务端愉快地进行TCP之后结束连接。
而在结束后,客户端重发的SYN报文才到达,如果是2次握手,则服务端也会痛快地决定建立连接,给客户端发送信息,等待客户端的信息等等,浪费自身和网络资源。
为什么需要4次挥手
流程
四次握手流程如下:假设数据先发送完毕的是客户端
客户端数据发送完毕,发送FIN报文
服务端针对1的FIN发送ACK报文
服务端数据发送完毕,发送FIN报文,此报文携带2报文中的ACK确认号
客户端针对2的FIN发送ACK报文
注意点:服务端收到ACK后可立即关闭连接,而服务端在发送完ACK后不能立即关闭连接,需要等待一段时间后,未再收到服务端的报文,才能关闭连接。
4次挥手的目的
目的:
每个TCP实体都既作为发送方,也作为接收方
a. 作为发送方:确认【对方已收到所有报文】
b. 作为接收方:确认【对方确认[自己已收到所有报文]】
为什么4次挥手就能满足以上目的
作为晚结束的那一方(如以上流程中的服务端),在收到4后就满足a,并满足了b,为什么呢?因为3报文中也携带着对客户端FIN报文的ACK确认号,当服务端收到了4报文,则服务端确认客户端收到了3报文,则满足b。
作为早结束的那一方(如以上流程中的客户端),收到2的ACK就满足a,在设定时间内未收到服务端反馈则认为满足了b,为什么呢?若服务端未收到4报文,则会超时重传,要求客户端重新发送4报文;若服务端收到4报文则直接关闭连接。客户端在足够长的时间未收到服务端的超时重传报文,则认为服务端已关闭连接,即客户端是通过服务端连接已关闭来满足b条件的。
我认为这个小结是4次握手的本质原因,洞察4次挥手的目的。