TCP连接管理
TCP是面向连接的协议,TCP传输连接的建立和释放是每一次面向连接的通信中必不可少的过程。TCP的传输连接包括3个状态:连接建立、数据传输和连接释放。
连接建立
最开始的时候客户端和服务器都是处于CLOSED状态。主动打开连接的为客户端,被动打开连接的是服务器。
- 首先,请求端(客户端)发送一个包含SYN标志的TCP报文,SYN即同步(Synchronize),同步报文会指明客户端使用的端口以及TCP连接的初始序号;
- 第二步,服务器在收到客户端的SYN报文后,将返回一个SYN+ACK的报文,表示客户端的请求被接受,同时TCP序号被加1,ACK即确认(Acknowledgment)。
- 第三步,客户端也返回一个确认报文ACK给服务器端,同样TCP序列号被加1,到此一个TCP连接完成。此时,Z=X+1。
为什么TCP客户端最后还要发送一次确认呢?
一句话,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
数据传输
三次握手最后一次握手,当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
下图所示,通信双方主机中应用进程之间的数据传输是字节流方式的。发送方主机将来自进程的数据放到该TCP连接的发送缓存里,然后不时地从发送缓存里取出一块数据准备发送。
连接释放
为什么客户端最后还要等待2MSL?
MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。2MSL即两倍的MSL,TCP的TIME_WAIT状态也称为2MSL等待状态,当TCP的一端发起主动关闭,在发出最后一个ACK包后,即第3次握手完成后发送了第四次握手的ACK包后就进入了TIME_WAIT状态,必须在此状态上停留两倍的MSL时间,等待2MSL时间主要目的是怕最后一个ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。TTL与MSL是有关系的但不是简单的相等的关系,MSL要大于等于TTL(生存时间)。
上图为TCP连接释放中的4次挥手过程。假设A的应用进程先向B发出连接释放请求,并且不再发送数据。TCP通知对方要释放A到B这个方向的连接,将发往主机B的TCP报文段头部的FIN标志置为1,其序号x等于前面已传送过去的数据的最后一个字节的序号加1。
主机B收到释放连接通知后即发出确认,其序号为x+1,同时通知高层应用进程。这样,从A到B的连接就释放了,连接处于半释放状态相当于主机A向主机B说:"我已经没有数据要发送了,但如果你还发送数据,我仍接收"。
此后,主机B不再接收主机A发来的数据。但若主机B还有一些数据要发往主机A,则可以继续发送。主机A只要正确收到数据,仍应向主机B发送确认。在主机B向主机A的数据发送结束后,其应用进程通知TCP释放连接。主机B发出的连接释放报文段必须将FIN位置1,并使其序号y等于前面已传送过的数据的最后一个字节的序号加1,而且必须重复上次已发送过的ACKSEQ=x+1。主机A必须对此发出确认,给出ACKSEQ=y+1。这样才把从主机B到A的反方向连接释放掉。主机A的TCP再向其应用进程报告,整个连接全部释放。
来源:CSDN
作者:浅浅爱默默
链接:https://blog.csdn.net/weixin_43625577/article/details/84957629