运输层—TCP的连接管理

TCP是面向连接的协议,TCP的运输连接有三个阶段:建立连接、数据传送、连接释放。

我们通过下面的图来理解TCP的连接:
首先,最初两端的TCP进程都处于一种CLOSD的状态,A作为客户,B作为服务器,这时候A主动打开连接,B是被动打开连接的,B的TCP服务器先创建传输控制块TCB(Transmission Control Block),准备接受连接的请求,进入到LISTEN状态,A的TCP进程也创建TCB,然后向B发送连接请求,首部中的同步位SYN=1,同时选择一个初始序号seq = x(SYN报文段不能携带数据,但是要消耗一个序号),这时候,A就进入到SYN-SENT。B收到了A发送的请求之后,需要进行确认,在确认报文段中,SYN和ACK都为1,确认号是ack = x + 1(下一个希望收到的序号为x+1),同时也有一个自己的初始序号y。这时候B就进入到了SYN-RCVD状态,接下来还有第三次的确认,这是很关键的,当A收到了B的确认报文之后,需要对B发送一个确认报文,ACK为1,序号seq = x+1,ack为y+1。这之后,A和B就进入到了ESTAB-LISHED状态。通过这样的三次握手(three - way handshake),连接就正式建立了。
可能有很多人会疑问为什么需要第三次确认,主要是防止已经失效的连接请求报文段突然传到了服务器,产生不应该的连接。例如A发出了一个连接请求,但是这个请求由于网络问题滞留在了网络中,由于超时计时器的时间到了,所以A进行重新发送请求,进行了一次连接,然后这次连接结束之后。之前滞留在网络中的那个请求又到达了B,如果没有第三次确认的话,那么这次连接就直接建立了,但是实际上A这时候是没有进行发送请求建立连接的。
下面我们继续通过一张图来了解TCP连接的释放:

连接建立成功之后,A和B都处于ESTABLISHED状态,A的应用进程先向TCP发出连接释放报文段。并停止发送数据,主动关闭TCP连接,A把连接释放报文段的首部的FIN设置为1(FIN报文段即使不携带数据,它也要消耗一个序号),然后序号seq = u(u等于前面已经传送的数据的最后一个字节的序号加1),这时候A就进入到了FIN-WAIT-1状态。B收到了连接释放请求之后需要做出确认,确认号是ack = u+1,报文段自己也序号有一个序号,seq = v(v等于B前面传送过的数据的最后一个字节的序号加上1),然后B就进入了CLOSE-WAIT状态。这时候的TCP是一种半关闭状态(half-close),A已经没有数据要发送给B了,但是如果B要发送数据给A,A还是要接受数据的。A收到了B的确认,就进入了FIN-WAIT-2状态。如果B不需要再向A发送数据了,B就要通知TCP释放连接了,这时候B需要向A发送报文段,FIN和ACK都为1,seq = w(在半关闭状态可能又发送了很多数据),ack = u+1。A在收到了B发送的请求之后,就进去了TIME-WAIT状态,接着还要给B也发送一个确认。
这里可能大家又有一个疑问了,为什么A还要等待2MSL(Maximum Segment Lifetime)的时候,而不是直接就关闭。这里有两个原因:
1、保证最后对B的确认能到达B,如果这个确认丢失了,那么B会超时重传这个请求,这个等待时间就为这些操作提供了足够的时间。如果不等待就直接释放连接的话,发生丢失的话,就无法收到B通过超时重传的请求,也就不能重新给B发送确认。
2、和建立连接相同,为了防止已经失效的连接请求出现。
所以TCP的连接释放是要进行四次握手。
除了最后A需要等待2MSL的时间外,TCP还设置了一个保活计时器(keepalive timer),主要用于这种情况:如果客户已经主动建立TCP连接,但是这个时候突然主机出现了故障,不能进行后续操作了,作为服务器,不能够就一直等待客户这边进行响应。服务器在每一次收到了客户的数据之后,就重新设置保活计时器,如果超过了时间,那么就发送一个探测报文段,如果连续发送10个探测报文段都没有反应,服务器就直接关闭这个建立。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值