三次握手和四次断开原理

TCP的三次握手和四次断开的实质就是TCP通信的断开和链接。

三次握手

目的是为了让客户端和服务端分别确认自己和对方接收和发送消息的能力是正常的,为了对每次发送的数据数量进行跟踪与协商,确保数据段的发送和接收同步,根据所接收到的数据量而确认数据发送、接收完毕后何时撤销联系,并建立联系。

三次握手原理

第一次握手:客户端发送一个带有SYN(synchronize)标志的数据包给服务端

第二次握手:服务端接收成功后,回传一个带有SYN/ACK标志的数据包传递确认信息,表示我收到了

第三次握手:客户端再回传一个带有ACK标志的数据包,表示我知道了,握手结束

其中:SYN标志位置1,表示建立TCP连接;ACK标志表示验证字段。

三次握手过程详细说明

初始时:客户端处于Closed状态,服务器处于Listen状态

第一次握手:客户端发送SYN报文给服务器,初始序列号为x(seq=x),此时客户端处于SYN_SENT状态;这时,客户端可以知道自己的发送能力正常,服务器可以知道自己的接收能力正常。

第二次握手:服务器通过自己的SYN报文给与客户端确认和响应,服务器进入SYN_RECV状态;这时客户端知道服务器的收发能力正常,自己的收发能力正常,服务器知道自己的收发能力正常,但不知道客户端接受能力正常,因此需要第三次握手。

SYN=1,表示为连接请求报文,也不能携带数据

seq=y,服务器序列号为y

ACK=1,表示确认客户端序列号有效,此时确认号(ack)有值

ack=seq+1,ack的值为客户端传来的序列号(seq)加1,即ack=x+1

第三次握手:客户端收到服务器的SYN+ACK的包,此时客户端处于ESTABLISHED(已确认)状态,表示客户端和服务器都表示同意连接,因此客户端发送一个ACK报文,ack仍为序列号+1,即y+1,即x+1;这时服务器可以确认客户端收发能力正常;第三次握手可以携带数据。

SYN=1或ACK=1表明这是一个连接请求报文

SYN=1时的报文不能携带数据,如果可以携带数据的话,如果有人在第一次握手的SYN报文放入很多数据,重复发送大量的这些报文,服务器就会消耗大量内存缓存这些报文,服务器就更容易被攻击。

完成第一次和第二次握手后的TCP连接,将socket放到半连接队列中,完成三次握手后,socket会从半连接队列移到全连接队列,当调用accpet函数时,从全连接队列中返回可用的socket给用户进程。

四次断开

即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送四个包已确认连接的断开。

四次断开的原理

第一次断开:客户端发送一个FIN,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1状态

第二次断开:服务端收到FIN后,发送一个ACK给客户端,确认序列号为收到的序列号+1(与SYN相同,一个FIN占用一个序列号),服务端进入CLOSE_WAIT状态

第三次断开:服务器发送一个FIN,用来关闭服务端到客户端的数据传送,服务端进入LAST_ACK状态

第四次断开:客户端收到FIN后,客户端进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为序号+1,服务端进入CLOSED状态,完成四次断开

四次断开过程详细说明

刚开始客户端和服务器端都处于ESTABLISHED状态,假如客户端发起关闭请求;

第一次断开:客户端向服务器发送FIN报文(FIN=1,seq=u),发完后进入FIN_WAIT_1状态,即主动关闭TCP连接,不再发送数据,但可以接收服务器发来的报文,等待服务器回复;

第二次断开:服务器接到FIN报文后,返回一个ACK报文(ACK=1,ack=u+1,seq=v),表明自己接收到此报文,服务器进入CLOSE_WAIT关闭等待状态,此时客户端就知道服务端接到自己的断开连接请求,进入到FIN_WAIT_2状态,TCP处于半关闭状态,但服务器端可能还有数据要传输。

第三次断开:服务器关闭客户端连接,发送FIN报文(FIN=1,seq=w,ack=u+1)给客户端,此时服务器处于LAST_ACK状态,等待客户端回应。

第四次断开:客户端收到FIN报文后,发送一个ACK(ACK=1,ack=w+1,seq=u+1)给服务器作为应答,此时客户端处于TIME_WAIT状态,这个状态是为了等待足够的时间以确保TCP接收到连接中断请求的确认。

注意:这时服务器到客户端的TCP连接并未被释放,客户端需要经过等待2MSL(MSL表示一个报文的来回时间)后才会进入CLOSED状态,这样做的目的是确保服务器收到自己的ACK报文,如果在规定时间没有收到客户端发的ACK,那么服务器会重发FIN,客户端再次收到FIN报文,就知道自己的ACK丢了,然后会重发ACK给服务器。服务器收到ACK后,就会关闭连接,处于CLOSE状态了。

等待2MSL的原因:
防⽌客户端最后⼀次发给服务器的确认在⽹络中丢失以⾄于客户端关闭,⽽服务端并未关闭,导致资源的浪费。
等待最⼤的2msl可以让本次连接的所有的⽹络包在链路上消失,以防造成不必要的⼲扰。
如果客户端直接closed,然后⼜向服务端发起了⼀个新连接,我们不能保证这个新连接和刚关闭的连接的端⼝号是不同的。假设新连接和已经关闭的⽼端⼝号是⼀样的,如果前⼀次滞留的某些数据仍然在⽹络中,这些延迟数据会在新连接建⽴后到达服务端,所以socket就认为那个延迟的数据是属于新连接的,数据包就会发⽣混淆。所以客户端要在TIME_WAIT状态等待2倍的MSL,这样保证本次连接的所有数据都从⽹络中消失。

参考资料:

原文链接:https://blog.csdn.net/sutong_first/article/details/126540687

原文链接:https://blog.csdn.net/m0_38106923/article/details/108292454

原文链接:https://blog.csdn.net/weixin_45393094/article/details/104965561

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值