tcp连接的建立与释放

1、TCP是面向连接的协议。

运输连接时用来传送TCP报文的。TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。因此,运输链接就有三个阶段,即:连接建立、数据传送和连接释放。

TCP连接建立过程中要解决以下三个问题:

1)要能使每一方都确知对方的存在。

2)要允许双方协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等)。

3)能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。

2、TCP的连接建立

 

上面给出的连接建立过程叫做三次握手

2.1、为什么A的最后还要发送一个确认报文呢?

这主要是为了防止已经失效的连接请求报文段突然又传送到了B,因而产生错误。所谓“已失效的连接请求报文段”是这样产生的。考虑一种正常情况。A发出连接请求,但因连接请求报文丢失而未收到来自B的确认。于是A再次重传一次连接请求。后来收到了确认,建立连接。数据传输完毕后,就释放了连接。A共发送了两个连接请求报文段,其中第一个丢失,第二个到达了B。没有“已失效的连接请求报文段”。

现假定出现一种异常情况,即A发出的第一个连接请求报文段并没有丢失,而是在某个网络节点长时间滞留了,以致延误到连接释放之后的某个时间才到达B。本来这是一个早已经失效的报文段。但B受到此失效的连接请求报文段后,就误认为是A又发出了一次新的连接请求。于是就向A发出确认报文段,同意建立连接。假定不采用三次握手,那么只要B发出确认,新的连接就建立了。由于现在A并没有发出建立连接的请求,因此不会理睬B的确认,也不会向B发送数据,但B却以为新的运输连接已经建立了,并一直等待A发来数据。B的许多资源就这样白白浪费了。

采用三次握手的办法就可以防止上述现象的发生。例如在刚才的情况下,A不会向B的确认发出确认。B由于收不到确认,就知道A并没有要求建立连接。

2.2、假设我们发送的第三个ACK报文段丢失了怎么办?

答:当Client段收到了ServerSYN+ACK应答后,其状态变为ESTABLISHED,并发送ACK包给Server;如果此时ACK在网络中走丢了,没有送达到服务器端,那么Server端该TCP连接的状态为SYN-RECV,并且一次等待一定的时间重新发送SYN+ACK包给客户端,直到连接正常的完成建立。

2.3、为什么TCP连接的建立要消耗序列号?

答:设想一下,如果TCP连接的建立不需要发送序列号,那么黑客要想攻击你的服务器不是变得非常简单的一件事,只要伪造TCP连接建立报文对你的服务器进行攻击,我们的服务器时刻都处在危险状态,所以TCP连接的建立不仅仅需要消耗序列号,还要求序列号算法越随机越好,黑客不能伪造出你的序列号,就无法通过TCP连接建立报文段对你的服务器进行攻击。

3、TCP连接的释放

 

上面给出释放连接的过程叫做四次挥手

请注意,当最后一个确认报文发送完毕之后,TCP连接还没有完全的释放掉。必须要经过时间等待计时器设置的2MSL时间后,A才进入到CLOSED状态,时间MSL叫做最长报文段寿命,建议设置为2分钟。单着完全是从工程上来考虑的,对于现在的网络MSL=2分钟可能太长了一些,因此TCP允许不同的实现可根据具体情况使用更小的MSL值。因此,从A进入到TIME-WAIT状态后,要经过4分钟才能进入到CLOSED状态,才能开始建立下一个新的连接。当A撤销香影的传输控制块TCB后,就结束了这次的TCP连接。

3.1、为什么ATIME-WAIT状态必须等待2MSL的时间呢?这里给出两个理由。

第一,为了保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段有可能会丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段,接着A重传一次确认,重新启动2MSL计时器。最后AB都能正常进入到CLOSED状态。如果ATIME-WAIT状态不等待一段时间,而是在发送完ACK报文段后立即释放连接,那么就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段,这样,B就无法按照正常步骤进入CLOSED状态。

第二,防止我们之前提到的“已失效的连接请求报文段”出现在本连接中。A在发送完最后一个ACK报文段后,再经过2MSL,就可以使本链接持续时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。

3.2、除时间等待计时器外,TCP还设有一个保活计时器。

设想有这样的情况:客户已主动与服务器建立了TCP连接。但后来客户端的主机突然出现了故障。显然,服务器以后就不能再收到客户发来的数据。因此,应当有措施使得服务器不要在白白的等待下去。这个就是使用保活计时器。服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置通常是两个小时。偌两个小时没有收到客户的数据,服务器就发送一个探测报文段,以后则每隔75分钟发送一次。若一脸发送10个探测报文段后仍无客户的响应,服务器就认为客户端出现了故障,接着就关闭这个连接。

更多linux、网络、shell、数据库等相关技术想和博主交流的,致信邮箱,大家互相学习alec1312linux@163.com
原文地址:https://www.cnblogs.com/alec1312/p/5847678.html