【计算机网络】TCP的运输连接管理(三次握手、四次挥手)

TCP的运输连接管理

TCP是面向连接的协议,TCP运输连接的建立和释放是每次数据传输必不可少的过程。因此面向连接的通信有三个阶段:连接建立、数据传输、连接释放。

1. TCP的连接建立

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

  • 使每一方能够确认对方的存在。
  • 允许双方协商一些参数(如最大窗口值,是否使用窗口扩大选项等)。
  • 能够对运输实体资源(如缓存大小、连接表等)进行分配。

TCP连接的建立采用客户-服务器方式,由客户端主动发起连接建立,服务器被动接收连接建立请求。(好像也存在同时主动发起连接建立的情况)

TCP连接的过程叫做握手,因为在客户和服务器之间交换了三个报文段,称为"三次握手"或"三报文握手"(three way handshake, three message handshake)。

在这里插入图片描述


最初客户端和服务器都处于CLOSED状态。服务器的TCP进程先创建传输控制块(Transmission Control Block),准备接收客户端的连接请求,然后就进入LISTEN状态。客户端的TCP进程创建连接时,也是先创建一个传输控制块TCB,并向服务器发送连接请求报文段。这时首部中的SYN=1,并选择一个初始序号。TCP规定,SYN报文段不能携带数据,但要消耗一个序号。这时客户端就进入SYN-SENT阶段。服务端收到连接请求报文后,如果同意建立连接,就发送一个连接确认报文段。这时首部的SYN=1,ACK=1,并选择一个初始序号。由于是SYN报文段,因此也不能携带数据。这时服务器就进入SYN-RCVD状态。客户端收到连接确认报文段后,向服务器发送确认。这时首部的ACK=1。TCP规定,ACK报文段可以携带数据,但如果不携带数据则不消耗序号。这时客户端也进入了ESTABLISHED状态。服务器收到客户端的确认后,也进入ESTABLISHED状态,连接就算建立成功了。(我觉得由于分组可能丢失,服务器可能进行重传,客户端其实可以适当推迟进入ESTABLISHED状态,只要经过2MSL没有收到重传报文段就可以认为连接建立了,这段时间也不会有数据传输)

连接建立过程中服务器发送SYN+ACK的过程其实也可以拆成两步,即先发送确认ACK,在发送SYN,这样就变成了四次握手,但效果是一样的。

为什么需要三次握手而不是两次握手,最后一次握手主要是为了防止失效的连接请求突然到达服务端,造成错误,使得服务器资源被浪费。三次握手即服务器需要客户端对连接建立进行再确认才建立连接,否则就认为发生了某些问题不建立连接。

2. TCP的连接释放

连接释放过程需要考虑到连接释放时是否还需要数据传送。因为TCP是全双工通信,释放连接需要释放两个方向的连接,即客户端释放一条连接,服务器释放一条连接。另外可以看出,由于服务端在TCP连接过程中的被动地位,TCP的连接管理都会为一些偶然情况引发的对服务端不利的情况作考虑。

在这里插入图片描述


TCP数据传输结束后,双方都可以释放连接。这时双方的状态还都是ESTABLISHED。假如客户端要求主动释放连接,则客户端发送连接释放报文段,这时首部中FIN=1,并进入FIN-WAIT-1状态。TCP规定,FIN报文段总是消耗掉一个序号。服务器收到连接释放报文后,先发送确认报文段,首部ACK=1,并进入CLOSE-WAIT状态。客户端收到确认报文后,什么都不做,进入FIN-WAIT-2状态。但这时服务器仍然可以向客户端发送数据。服务器发送完成之后,也发送连接释放报文段,这时首部FIN=1,ACK=1,确认号必须重复上次对FIN报文段的确认的确认号,进入LAST-ACK状态。客户端收到服务器的连接释放报文后,发送确认报文段,ACK=1,进入TIME-WAIT状态。客户端设置一个时间等待计时器,计时2MSL,等待没有收到重传报文后才进入CLOSED状态。MSL(Maximum Segment Lifetime,最长报文段寿命),TCP允许不同的实现根据具体情况使用比2min更小的MSL值。服务器收到最后的确认报文段后,就进入CLOSED状态。连接也就算关闭了。

之所以要设置一个TIME-WAIT状态,主要有两个原因。一是由于网络原因服务器可能没有收到最后的确认报文,那么在2MSL时间内,客户端就能收到服务器的重传报文,这时客户端重新设置时间等待计时器并重新发送确认报文。这样就可以确保服务器能够收到确认报文。二是为了防止"已失效的连接报文段"出现在本连接中。(这块没看懂有啥明显关系……)

TCP的连接释放也称为四报文握手,或四次挥手。

除了时间等待计时器外,TCP还有一个保活计时器(keepalive timer)。假设客户端某一时刻突然故障了,但是服务端并不知道。如果客户端一直故障下去,这条连接也就没办法释放,白白浪费服务端的资源。因此服务器每收到一次来自客户端的数据,就重新设置保活计时器。如果两小时内没有收到客户端的数据,那么就启动探测,并每隔75秒再发送探测报文段。如果连续10个探测报文段仍然没有收到客户端的响应,服务端就认为客户端出现问题,并关闭连接。

保活计时器涉及到三个参数:

  • tcp_keepalive_time: KeepAlive的空闲时长,或者说每次正常发送心跳的周期,默认值为7200s(2小时)
  • tcp_keepalive_intvl: KeepAlive探测包的发送间隔,默认值为75s
  • tcp_keepalive_probes: 在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包次数,默认值为9(次)

3. TCP的有限状态机

在这里插入图片描述


(看看就行了……不知道有啥用……)

4. 同时建立或释放连接的处理

前面讨论的都是客户端主动,服务端被动情况下的处理。如果连接同时建立,或者同时释放,应该如何处理呢。
直接上俩图来看吧。

在这里插入图片描述
在这里插入图片描述

同时建立连接:任何一方,只要发送连接建立报文就进入SYN-SENT状态;收到连接建立报文就进入SYN-RCVD状态,并发送ACK;收到ACK后就进入ESTABLISHED状态。

同时释放连接:任何一方,只要发送连接释放报文段就进入FIN-WAIT-1状态;收到连接释放报文段就进入CLOSING状态,并发送ACK;收到ACK后就进入TIME-WAIT状态,时间等待计时器计时结束进入CLOSED状态。




参考资料:

《计算机网络第七版》谢希仁
https://blog.csdn.net/oyhy_/article/details/70201855

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值