(3) TCP状态转换

一、 TCP状态转换

TCP涉及连接建立和连接终止的操作可以用状态转换图(state transition diagram)来说明,如图1所示:
在这里插入图片描述

图1 TCP状态转换图

图1图解:

  • TCP为一个连接定义了11种状态,并且TCP规则规定如何基于当前状态及在该状态下所接收的分节从一个状态换到另一个状态。举例来说,当某个应用进程在CLOSED状态下执行主动打开时,TCP将发送一个SYN分节,且新的状态是SYN_SENT。如果这个TCP接着接收到一个带ACK确认的SYN分节,它将再发送一个ACK确认,且新的状态是ESTABLISHED(已建立的)。这个最终状态是绝大多数数据传送发生的状态。
  • 自ESTABLISHED状态引出的两个箭头处理连接的终止。如果某个应用进程在接收到一个FIN分节之前调用close(主动关闭),那就转换到FIN_WAIT_1状态。但如果某个应用进程在ESTABLISHED状态期间接收到一个FIN分节(被动关闭),那就转换到CLOSE_WAIT状态。
  • 图1中使用粗实线表示通常的客户状态转换,用粗虚线表示通常的服务器状态转换。图3中还注明存在两个未曾讨论的转换:一个为同时打开(simultaneous open),发生在两端几乎同时发送SYN分节并且这两个SYN分节在网络中交错的情形下;另一个为同时关闭(simultaneous close),发生在两端几乎同时发送FIN分节的情形下。将会在后续文章中记录,它们是可能发生的,不过非常罕见。
  • 展示状态转换图的原因之一是给出11种TCP状态的名称。这些状态可使用netstat显示,它是一个在调试客户端、服务器应用时很有用的工具。将在后续文章中记录。
1.1 TCP状态转换分组观察

图2展示了一个完整的TCP连接所发生的的实际分组交换情况,其中包含了连接建立、数据传送和连接终止3个阶段的分组交换和其中的状态转换。
在这里插入图片描述

图2 TCP连接分组交换

图2图解:

  • 图2中客户段建立连接时通知服务器一个值为536的MSS(表明该客户端只实现了最小重组缓冲区大小),服务器通知客户端一个值为1460的MSS(以太网上IPv4的典型值)。不同方向上MSS值不相同不成问题。
  • 服务器对客户端请求的确认是伴随其应答发送的。这种做法称为捎带(piggybacking),它通常在服务器处理请求并产生应答的时间少于200ms时发生的。如果服务器耗用更长时间,譬如1s,那么将看到先是确认后是应答。
  • 图2中最后展示的是终止连接的4个分节。注意,执行主动关闭的那一端(本图中是客户端执行主动关闭)进入了TIME_WAIT状态。

图2注意:

  • 如果图2的TCP连接的整个目的仅仅是发送一个单分节的请求和接收一个单分节的应答,那么使用TCP有9个分节的开销(资料书籍中翻译是8个分节?)
  • 如果改用UDP,那么只需交换两个分组:一个承载请求,一个承载应答。
  • 然而从TCP切换到UDP将丧失TCP提供给应用进程的全部可靠性,迫使可靠服务的一大堆细节从传输层TCP转移到UDP应用进程。TCP提供的另一个重要特性即拥塞控制也必须由UDP应用进程处理。
  • 尽管如此,仍需知道许多网络应用是使用UDP构建的,因为它们需要交换的数据量较少,而UDP避免了TCP连接建立和终止所需的开销。
1.2 TIME_WAIT状态
1.2.1 最长分节生命期 MSL

TCP中有关网络编程最不容易理解的是它的TIME_WAIT状态。在图3中可以看到执行主动关闭的那一端经历了这个状态。该端点停留在这个状态的持续时间是最长分节生命期(maximum segment lifetime,MSL)的两倍,有时候称之为2MSL。

任何TCP实现都必须为MSL选择一个值。RFC 1122 [Braden 1989]的建议是2分钟,不过源自Berkeley的实现传统上改用30s这个值。这意味着TIME_WAIT状态的持续时间在1分钟到4分钟之间。

MSL是任何IP数据报能够在因特网中存活的最长时间。我们知道这个时间是有限的,因为每个数据报含有一个称为跳限(hop limit)的8位字段(在IPv4的TTL字段和IPv6的跳限字段),它的最大值为255。

尽管这是一个跳数限制而不是真正的时间限制,但可以假设:具有最大跳限(255)的分组在网络中存在的时间不可能超过MSL秒。

1.2.2 分节在网络中的“迷途”

分节在网络中的“迷途”通常是路由异常的结果。

假设1:某个路由器崩溃或某两个路由器之间的某个链路断开时,路由协议需花数秒钟到数分钟的时间才能稳定并找出另一条通路。在这段时间内有可能发生路由循环(路由器A把分节发送给路由器B,而B再把他们发送给A),比较关心的分节可能就此陷入这样的循环。

假设2: 陷入“迷途”的分节是一个TCP分节,在它迷途期间,发送端TCP超时并重传该分组,而重传的分节却通过某条候选路径到达最终目的地。然而不久之后(自迷途的分节开始起其旅程起最多MSL秒以内)路由循环修复,早先迷失在这个循环中的分节最终也被送到目的地。这个原来的分节称为迷途的重复分组(lost duplicate)或漫游的重复分组(wandering duplicate)。TCP必须正确处理这些重复的分组。

1.2.3 TIME_WAIT状态存在的理由
  • 理由1: 可靠的实现TCP全双工连接的终止
  • 理由2: 允许老的重复分节在网络中消逝

理由1注解:

  • 可根据图2假设最终的ACK确认丢失了来解释。服务器将重新发送它的最终那个FIN,因此客户端必须维护状态信息,以允许它重新发送最终那个ACK确认。
  • 要是客户端不维护状态信息,它将响应以一个RST(另外一种类型的TCP分节),该分节将被服务器解释成一个错误。
  • 如果TCP打算执行所有必要的工作以彻底终止某个连接上两个方向的数据流(即全双工关闭),那么它必须正确处理连接终止序列4个分节中任何一个分节丢失的情况。
  • 上述文本列举也说明了为什么执行主动关闭的那一端是处于TIME_WAIT状态:因为可能不得不重传最终那个ACK确认的那一端。

理由2注解:

为理解存在TIME_WAIT状态的第二个理由,作如下假设说明:

  • 假设在12.106.32.254的1500端口和206.168.112.219的21端口之间有一个TCP连接。先关闭这个连接,过一段时间后在相同的IP地址和端口之间建立另一个连接。后一个连接称为前一个连接的化身(incarnation),因为它们的IP地址和端口号都相同。

  • TCP必须防止来自某个连接的老的重复分组在该连接已终止后再现,从而被误解成属于同一连接的某个新的化身。为做到这一点,TCP将不给处于TIME_WAIT状态的连接发起新的化身。

  • 既然TIME_WAIT状态的持续时间是MSL的2倍,这就足以让某个方向上的分组最多存活MSL秒即被丢弃,另一个方向上的应答最多存活MSL秒也被丢弃。

  • 通过实施这个规则,就能保证没成功建立一个TCP连接时,来自该连接先前化身的老的重复分组都已在网络中消逝了。

但是TIME_WAIT规则存在一个例外:

  • 如果到达的SYN的序列号大于前一化身的结束序列号,源自Berkeley的实现将给当前处于TIME_WAIT状态的连接启动新的化身。
  • TCPv2中对这个情况进行了详细的叙述。它要求服务器执行主动关闭,因为接收下一个SYN的那一端必须处于TIME_WAIT状态。rsh命令具备这种能力。RFC 1186[Jacobson, Braden, and Zhang 1990]讲述了有关这种情形的一些陷阱。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值