如果两个人想要有一个正常的通话,必须保证张飞能听得到, 于是有了第一次握手,刘备问张飞,你能听得到吗?
张飞听到刘备的请求,开始第二次握手,说,我能听到,你呢?
刘备听到了张飞的话,首先自己知道了,原来张飞那小子能听到我说话,于是建立了连接,但是张飞那傻小子还等着刘备回信呢,在那犯嘀咕,我大哥到底能不能听到我说话,这个时候刘备开始了第三次握手,告诉张飞,我也可以听到你说话。张飞听到后,也建立了连接,至此,连接完成!
然后两人就开始得啵得啵得!
那么我们从专业的角度解读一下这个三次握手
第一次握手,发送方主动发起请求,SYN=1 表示我要建立连接,seq=x 表示序列号(用于甄别是哪一次的请求,序列号即被消耗掉了)
第二次握手,接收方接成功收到请求后,先是ACK=1 表示接收到了,SYN=1表示我也要建立连接,seq=y 表示序列号(用于甄别是哪一次的请求,序列号即被消耗掉了),ack=x+1,表示我想要你的序列号是 x+1;
第三次握手,发送方 ACK=1,表示我接收到了,seq=x+1 这是接收方要求要的,ack=y+1 表示下一次想要的序列号
其中第二次握手之后,发送方就已经建立了连接,第三次握手之后,接收方建立连接;
这就是我们前面提到的tcp报文结构
再来看一下tcp标记
第二次握手
第三次握手
为什么要发送第三个确认报文?其实主要还是为了给这次握手做个了结,如果没有第三次会发生什么情况呢? 弄清这个问题,我们需要先弄明白三次握手的目的是什么,能不能只用两次握手来达到同样的目的。
第一次握手:客户端发送网络包,服务端收到了。 这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。 第二次握手:服务端发包,客户端收到了。 这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。 第三次握手:客户端发包,服务端收到了。 这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。 因此,需要三次握手才能确认双方的接收与发送能力是否正常。
试想如果是用两次握手,则会出现下面这种情况:
如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。
还是刚才打电话的栗子,如果是两次握手,第一次刘备说,你能听得到吗?但是是张飞没听到,可能是某一个瞬间 信号不好,网络阻塞,或者被外星人劫持,由于刘备没有收到张飞的回应,又发了一次请求,说,小飞飞,你听得到吗?这时张飞听到了,开始第二次握手,回答说我听到了,此时连接建立!通话结束后,张飞刚想走,这个时候听到大哥第一次的呼唤,你听得到吗吗吗吗????于是张飞又一次建立了连接,而此时,刘备已经去白帝城了,而张飞一直在等,等他的大哥。。。。。很悲剧的故事,对不对,哈哈,但是对于计算机来说,这是一种资源浪费!
先来通俗的,简单易懂的讲一下;比如下面这个场景
下课铃响,莫小贝对老夫子说,夫子,下课了,这是第一次挥手,莫小贝就不再跟老夫子互动了,坐等下课(等待),夫子也不看莫小贝的反应了(关闭等待),
但是夫子爱拖课(大家最烦这种套路的老师啦,哈哈)!说,我知道了,等我讲完这一点就下课,于是莫小贝还得干等(第二次等待),这是第二次挥手,
老夫子孤独的讲了五分钟后,说我讲完了,下课!这是第三次挥手(最后确认)
莫小贝说,我知道了,你大爷的(有点不尊师重道哈,要批判)!这是第四次挥手
至此,四次挥手完毕,tcp释放连接
我们再从专业的角度解读一下
第一次挥手,发送方主动发起释放请求,FIN=1表示结束连接,seq=u和前面一样序列号
第二次挥手,接收方ACK=1表示接收方收到了,seq=v是 接收方的序列号,ack=u+1,表示下次希望接收的序列号
第三次挥手,接收方发起释放请求,FIN=1表示要释放,ACK=1表示接收到了释放请求,seq=w表示本次序列号,ack=u+1表示下次希望接收的序列号
第四次挥手,发送方ACK=1表示接收到了,seq=u+1,是第三次挥手要求的序列号,ack=w+1表示希望下次得到的序列号;
从上面可以看出,发送方发送断开请求后,接收方就关闭了等待,由于发送方没有接收到接收方的断开请求,就一直处于等待状态,只到第三次挥手,开始等待计时!而接收方在第四次挥手后就关闭了。发送方在等待计时结束后关闭
下面我们来说一说什么是 等待计时器
cat /proc/sys/net/ipv4/tcp_fin_timeout
,好了,这个点到为止!为什么要等待2MSL? 1.为了保证所有的报文都已经传送(或者过期) 2.为了保证发送方的ACK可以到达接收方,在2MSL时间内如果接收方没有收到发送方的ACK,则接收方会再次发起第三次挥手
第一次挥手
第二次挥手
第三次挥手
第四次挥手