ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

TCP四次会挥手

2021-03-16 10:01:22  阅读:166  来源: 互联网

标签:挥手 ACK 报文 TCP 四次 FIN 服务端 客户端


目录

四次挥手过程中状态名词

参考链接:https://blog.csdn.net/xwdpepsi/article/details/8097238

ESTABLISHED:代表一个打开的连接,数据可以传给用户

FIN-WAIT-1:等待远程TCP的连接中断请求,或先前的连接中断请求的确认

FIN-WAIT-2:从远程TCP等待连接中断请求

CLOSED-WAIT:等待从本地用户发来的连接中断请求

CLOSING:等待远程TCP对连接中断的确认

LAST-ACK:等待原来发向远程TCP的连接中断请求的确认

TIME-WAIT:等待足够的时间以确保远程TCP接收到连接中断请求的确认

CLOSED:没有任何连接状态

四次挥手的简单过程

刚开始客户端和服务端都处于ESTABLISHED的状态(可以进行数据传输),假如是客户端先发起断开连接请求,则:

  • 第一次挥手,客户端请求断开,发送FIN,seq=u
  • 第二次挥手,服务器端确认客户端的断开请求,返回ACK,ack=u+1,seq=v
  • 第三次挥手,服务器请求断开,返回FIN,ACK,ack=u+1,seq=w
  • 第四次挥手,客户端确认服务器的断开,发送ACK,ack=w+1,seq=u+1

在这四次挥手的过程中,ACK标志一直等于1

ack和seq的计算参考链接:https://blog.csdn.net/HappyRocking/article/details/78198776

四次挥手过程图

过程解析:

  • 第一次挥手:客户端发送一个FIN=1的TCP报文,报文中会指定一个序列号:seq=u,此时客户端FIN_WAIT_1的状态
  • 第二次挥手:服务端收到FIN报文后,会返回一个ACK报文,ack的值设置为客户端发送的u+1,以及发送一个自己的序列号seq=v,表明已经收到客户端FIN(想要断开连接的请求),此时服务端存处于CLOSED_WAIT的状态。
  • 第三次挥手:此时客户端收到服务端的确认结果后,进入了FIN_WAIT_2状态,如果服务端也想断开连接,和客户端第一个挥手一样,发给客户端一个FIN=1的TCP报文给客户端,此时依然会再发送一个ACK=1,确认序列号依然时u+1,此时的序列号seq=w,服务端进入LAST-ACK(最后确认状态)
  • 第四次握手:客户端收到服务端发来的FIN=1的TCP报文后,会再返回一个ACK=1的报文作为应答,且把服务端在第三次挥手发来的序列号作为ack的值(ack = w+1, 包确认机制中在发送连续包时,只需要对最后一次发送的数据包进行确认),此时客户端处于TIME_WAIT状态。需要等待一段时间(最长两个报文的时间——以确保服务端收到自己的ACK报文之后才会进入CLOSED状态,只要服务端不发消息,就默认其收到了),服务端这边收到来自客户端的ACK报文后,就处于关闭连接状态(CLOSED)

为什么三次握手,需要四次挥手

参考链接:https://blog.csdn.net/daocaoren1543169565/article/details/80535949

对于建立连接时的三次握手的过程中:因为当服务端收到客户端的SYN连接请求报文后,服务端返回SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的,这两个TCP报文可以直接一起返回

对于关闭连接时:当服务端收到FIN报文时,仅仅表示客户端不能发送数据了,但还能接收数据,服务端这边也未必将全部数据都发送给客户端了,所以不会立即关闭SCOKET,所以只能先回复一个ACK报文,告诉客户端,"你发的FIN报文我收到了"。只有等到我(服务端)所有报文都发送完了,我才能发送FIN报文,因此不能将两个报文一起发送,所以需要四步握手

为什们客户端发送ACK之后不直接关闭,需要等待一段时间才关闭

参考链接:https://www.jianshu.com/p/0a81dfb307d7

主要目的是:确保服务端已经收到客户端发送的ACK报文,如果没有收到的话,服务端会重新发送FIN+ACK报文(重新进入第三次挥手状态),客户端再次收到FIN报文,就知道发送给服务端的ACK报文丢失了,然后再次发送ACK报文

如果客户端不等待一段时间,而是发完ACK立即释放连接,则无法收到服务端重传的FIN+ACK报文,也不会重传ACK报文,这样服务端无法正常进入CLOSED状态

为什么等待的时间至少是2MSL(一个报文的来回时间)才关闭

参考链接:https://blog.csdn.net/yrx420909/article/details/104483591/

MSL最长报文段寿命Maximum Segment lifetime, MSL = 2

客户端一般会设置一个计时,如果超过了这个时间没有再次收到FIN+ACK报文,则代表服务端已经成功接收了ACK报文,然后客户端可以直接进入CLOSED状态

设置这个等待时间的原因:

1)保证客户端发送的最后一个ACK报文能够达到服务端

这个ACK报文有可能会丢失,使得处于服务端收不到对已发送的ACK+FIN报文的确认,服务端超时重传FIN+ACK报文,这样服务端能在2MSL的时间内收到这个重传的FIN+ACK报文,然后客户端重传一次ACK报文,再重新启动2MSL计时器,最后客户端和服务端都进入CLOSED状态

2)防止已经失效的请求报文段出现在新连接中

客户端在发送完最后一个ACK报文段,再经过2MSL,就可以使本连接持续时间内所产生的所有报文从网络消失,使得下一个新的连接中不会出现上一次连接中旧的报文段

标签:挥手,ACK,报文,TCP,四次,FIN,服务端,客户端
来源: https://www.cnblogs.com/Vicky1361/p/14541788.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有