tcp三次握手

参考链接
感谢前辈分享
https://blog.csdn.net/qq_38950316/article/details/81087809
在这里插入图片描述
在这里插入图片描述
tcp三次握手
首先服务器开启监听状态
客户端向服务器发送请求报文,同步状态SYN=1,确认状态ACK=0,序列号seq=x,此时进入同步已发送状态
服务器端接收到请求报文之后,发送确认报文,同步状态为SYN=1,确认状态ACK=1,确认号ack=x+1,序列号seq=y,服务器端进入同步已收到状态
客户端接收到请求报文之后,再次向服务器总发送确认报文,确认状态ACK=1,确认号ack=y+1,序列号seq=x+1,客户端进入已连接状态此时可以携带报文数据,如果不携带则不消耗序列号
服务器端收到确认报文之后,进入已连接状态,此时双方可以建立通信
为什么要进行三次握手?
当客户端向服务器发送请求的时候,很有可能因为网络的原因,请求滞留在某个节点中,这个时候,客户端重新发送了一个同样的请求,然后和服务器端建立链接进行了通信,之后链接释放,当网络中的拥塞变好的时候,第一次发送的请求到达了服务器,此时服务器向客户端发送确认报文,如果不是三次握手,这个时候就已经建立好了链接,然而客户端并没有发送的请求,因此不会理睬服务器端的确认报文,但服务器端认为新的链接已经建立,服务器就一直等待客户端发送数据,这样服务器端就浪费了很多的资源,如果是三次握手的话,服务器端没有收到客户端的确认报文,就会知道客户端没有链接请求。这样做就防止服务器端一直等待,浪费资源
在这里插入图片描述
四次挥手
因为tcp是全双工的,因此,每一个方向都要单独进行关闭,一方关闭了连接之后,另一方收到FIN标志之后,可以继续发送数据。首先进行关闭的一方执行主动关闭,另一方执行被动关闭
客户端主动关闭
客户端向服务器端发送链接释放报文,链接释放报文中终止标志FIN=1,序列号seq=u,等于前面已经传过来的数据的最后一个字节加1,此时客户端进入终止等待状态1
务器收到链接释放报文之后,发送确认报文,确认报文中确认标志ACK=1,确认号ack=u+1,序列号为seq=v,此时服务器端进入关闭等待状态,此时客户端向服务器端的链接已经释放,处于半关闭的状态,客户端已经没有数据要发送了但是服务器端要发送数据客户端还要继续的接收,关闭等待状态要持续整个关闭等待状态
客户端收到服务器的确认报文之后**,客户端进入终止等待状态2,等待服务器发送释放链接报文,在此之前还要继续接收服务器发送的数据
服务器端将最后的数据发送完毕之后,向客户端发送释放链接报文,释放链接报文中终止标志FIIN=1,ack=u+1,因为之前处于半关闭状态,服务器可能又发送了一些数据,因此,seq=w,此时
服务器端进入最后确认状态**,等待客户端确认
客户端收到服务器的链接释放报文之后,发送确认报文,确认标志ACK=1,确认号ack=w+1,序列号为seq=u+1,此时客户端进入时间等待状态,经过两倍的最长报文端寿命的时间之后,当客户端撤销响应的TCB控制块时候,才进入closed状态
服务器只要收到了客户端的确认报文,就会立即的进入closed状态,同样撤销TCB控制块后就结束了此此的TCP链接,可以看到服务器端结束要比客户端早

为什么要等待2MSL时间两个最长报文段寿命的时间?
按照道理讲,四个报文都发送完毕之后,我们可以直接进入closed状态了,但是我们必须假象网络是不可靠的,有可能最后客户端发送的ACK丢失,所以时间等待状态就是用来重发可能丢失的ACK报文的,在客户端发送出最后的ACK确认报欧文时候,该ACK报文丢失,如果服务器没有收ACK报文,将会不断的重发发送FIN链接释放报文,所以客户端不能立即关闭,关闭了之后就不呢个做出回应了,必须要确认server收到了该ACK文。客户端在发送ACK之后进入了时间等待状态,客户端会设置一个计时器,等待2MSL时间,如果在这个事件段内再次收到链接释放报文FIN,那么客户端会重发ACK并再次等待2MSL.所谓2MSL就是两倍的最长报文段寿命时间,MSL指的是一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间,如果到了2MSL客户端还没有再次收到FIN链接释放报文,那么客户端可以认为ACK已经被成功接收,结束TCP链接
另外防止三次握手中提提到的“已经失效的连接请求报文段”出现在本连接中,当客户端经过2MSL时间之后就可以是的本次链接持续的时间内所产生的所有报文都从网络中消失,保证下次重新链接的时候不会出现旧链接的请求报文。

为什么链接的时候是三次握手,而关闭的时候是四次握手?
因为服务器端收到客户端的SYN链接请求报文的时候,可以直接发送ACK和SYN的确认报文,其中ACK是用来进行应答的,而SYN报文是用来同步的。但是在关闭链接的时候,服务端收到释放链接报文FIIN的时候,可能不会立即关闭socket,所以智能先回应一个ACK报文,告诉客户端我已经收到FIN连接释放报文了,只有等待服务器端所有报文都发送完了之后,才能发送FIN释放链接报文报文,因此不能一起发送,(如果可以直接关闭,不需要继续发送的时候,将会跳过终止等待状态2,直接进入时间等待,这样只需要三次握手就可以)

如果已经建立了链接,但是客户端突然出现故障了怎么办?
TCP有一个保活计时器,显然客户端如果出现了故障之后,不能一直等下去浪费资源。服务器每次收到客户端请求的时候都会重新复位这个计时器,通常时间设置为2个小时,若一段时间内还没有收到客户端的任何数据,服务器端就会发送一个探测报文,以后每个一段时间75分钟发送一次,若一连串发送10个探测报文之后仍然没有反应,服务器就认为客户端出了故障,就接着关闭链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值