通俗易懂的理解TCP 三次握手 四次挥手通俗易懂的理解TCP 三次握手 四次挥手路飞博客

通俗易懂的理解TCP 三次握手 四次挥手

TCP很经典的一个问题,就是三次握手和四次挥手的问题,这也是一个高频的面试题,所以掌握这个知识点至关重要。看了网上的一些文章和公众号,我这里做了一个小小的总结和个人的理解,本人才疏学浅,难免存在纰漏,如果发现有错误的地方,欢迎指出。

首先需要知道的内容是:

三次握手:建立连接

四次挥手:关闭连接

SYN:同步连接序号,SYN=1(请求建立连接);

ACK:请求/应答状态,ACK=0(请求状态),ACK=1(应答状态);

FIN: 结束连线,FIN=0(结束连线请求),FIN=1(结束连线)。

一、三次握手

比喻篇:

TCP的三次握手可以想象成男生女生表白,这里做一个比喻男生(客户端)女生(服务端)

1)男生送消息给女生,告诉她,我喜欢你,可以做我女朋友吗? (第一次握手,男生——>女生

2)女生回复男生,我收到了,其实我也喜欢你。(第二次握手,女生——>男生

3)男生收到回复,告诉女生我会爱你一辈子。表白成功,双方在一起。(第三次握手,男生——>女生

通过上面例子,可以得知,男生和女生都知道要表述的意思已经传达给双方,并且收到了反馈意思,最后成功在一起。同理,三次握手的目的是为了确认客户端和服务端的收发功能是正常的,因此可以建立连接。

专业篇:

刚开始客户端和服务端都是处于关闭的状态,而且服务器 B 端一直处于监听的状态,时刻监听是否有建立连接的请求,接下来开始握手:

1)当有客户端需要建立连接的时候就会发送一个确定连接的报文,此报文是同步报文SYN = 1,并且会生成一个随机的序号 seq = x,这是第一次握手;
2)当服务端接收到请求连接报文的时候,会发送一个同步报文确认报文,此报文 SYN = 1,并且 ACK = 1,同时服务端也会随机生成一个 seq = y,并将 ack 设置成 x + 1,回传给客户端,这是第二次握手;
3)当客户端接收到服务端的 ACK 报文后,会回复一个 ACK 确认报文,用于确认确认报文已经收到,此报文 ACK = 1,seq = x + 1, ack = y + 1,这是第三次握手。

上面是整个三次握手的过程,现在我们分析一下为什么三次握手可以可靠的确定客户端和服务端都能支持的发送和接收数据。

第一次握手:第一次握手是客户端发送同步报文到服务端,这个时候客户端是知道自己具备发送数据的能力的,但是不知道服务端是否有接收和发送数据的能力;

第二次握手:当服务端接收到同步报文后,回复确认同步报文,此时服务端是知道客户端具有发送报文的能力,并且知道自己具有接收和发送数据的能力,但是并不知道客户端是否有接收数据的能力;

第三次握手:当客户端收到服务端的确认报文后,知道服务端具备接收和发送数据的能力,但是此时服务端并不知道自己具有接收的能力,所以还需要发送一个确认报文,告知服务端自己是具有接收能力的。

当整个三次握手结束过后,客户端和服务端都知道自己和对方具备发送和接收数据的能力,随后整个连接建立就完成了,可以进行后续数据的传输了。

看到这里,如果大家理解了就会知道很明显,两次握手是不行的,因为服务端并不知道客户端是具备接收数据的能力,所以就不能成为面向连接的可靠的传输协议。就像我们上面提到的打电话的例子,也是为了双方能够正常的进行交流,只不过我们现实生活中不会那么严谨,并不是每次都这样,但是程序是不一样的。

二、四次挥手

比喻篇:

TCP的四次辉手可以想象成男生女生分手,这里做一个比喻男生(客户端)女生(服务端)

1)男生送消息给女生,告诉她,我不爱你了,我们分手吧! (第一次挥手,男生——>女生

2)女生回复男生,我还爱着你,我不要分手【进入冷战期】。(第二次挥手,女生——>男生

3)女生发消息给男生,我想了很久,觉得还是分手吧,好聚好散。(第三次挥手,女生——>男生

4)男生收到消息,告诉女生我知道了,对不起,不是你不好,其实是我配不上你。分手成功,双方关系结束。(第四次挥手,男生——>女生

通过上面例子,可以得知,男生和女生都知道要表述的意思已经传达给双方,并且收到了反馈意思,最后成功分手,关系结束。同理,四次挥手的目的是为了让客户端和服务端双方都知道自己要关闭连接了。

专业篇:

1)客户端发起 FIN 断开连接的报文,携带随机生成的 seq 值 u,发送给服务端,并且自己处于 FIN-WSIT 状态,这是第一次挥手;
2)服务端接收到 FIN 报文后,回复一个确认报文,其中 ACK = 1,随机生成一个 seq,以及 ack = u + 1,这是第二次挥手;
3)当服务端数据发送完了过后,再发送一个 FIN 报文给客户端,通知客户端,服务端准备关闭连接了,此报文 FIN = 1,ACK = 1,ack = u + 1,seq = w,这是第三次挥手;
4)当客户端收到 FIN 确认报文时再发送一个FIN 的确认报文,其中 ACK = 1,seq = u + 1,ack = w + 1,并进入 TIME-WAIT 状态,当等待 2MSL 后关闭连接,这是第四次挥手。

第一次挥手客户端发起关闭连接的请求给服务端;

第二次挥手:服务端收到关闭请求的时候可能这个时候数据还没发送完,所以服务端会先回复一个确认报文,表示自己知道客户端想要关闭连接了,但是因为数据还没传输完,所以还需要等待;

第三次挥手:当数据传输完了,服务端会主动发送一个 FIN 报文,告诉客户端,表示数据已经发送完了,服务端这边准备关闭连接了。

第四次挥手:当客户端收到服务端的 FIN 报文过后,会回复一个 ACK 报文,告诉服务端自己知道了,再等待一会就关闭连接。

三、疑问

1、为什么握手要三次,挥手却要四次呢?
答:那是因为握手的时候并没有数据传输,所以服务端的 SYN 和 ACK 报文可以一起发送,但是挥手的时候有数据在传输,所以 ACK 和 FIN 报文不能同时发送,需要分两步,所以会比握手多一步。
2、为什么客户端在第四次挥手后还会等待 2MSL?
答:等待 2MSL 是因为保证服务端接收到了 ACK 报文,因为网络是复杂了,很有可能 ACK 报文丢失了,如果服务端没接收到 ACK 报文的话,会重新发送 FIN 报文,只有当客户端等待了 2MSL 都没有收到重发的 FIN 报文时就表示服务端是正常收到了 ACK 报文,那么这个时候客户端就可以关闭了。

部分内容转载于:
https://mp.weixin.qq.com/s/tlWDBDu7UBeXaz1LUxA3Jg
参考阅读:
https://blog.csdn.net/whuslei/article/details/6667471
https://blog.csdn.net/piexie8364/article/details/114536504
     

转载请注明:路飞博客 » 通俗易懂的理解TCP 三次握手 四次挥手