查看: 642|回复: 0

TCP的核心组件(下):确认号与确认机制

[复制链接]
发表于 2024-5-30 17:01:00 | 显示全部楼层 |阅读模式

本文是《从时序图看TCP》系列的第4篇,前3篇内容为:

01《通过时序图视角,看透TCP类业务故障》

02《高效排障:详解RST,判定连接重置根因》

03《TCP的核心组件(上):说说TCP序列号的运动规律


上篇文章和大家聊了关于TCP序列号的运动规律情况,本文将继续围绕该话题和大家探讨TCP确认相关机制——TCP确认号(Acknowledgment Number)、累积确认(Cumulative Acknowledgement)和延迟确认(Delayed Acknowledgement)。


  TCP的“确认号”是什么? 


TCP协议为了实现可靠传输,将它自己要发送的每一个字节都进行了“排序编号”,即Seq确认号(此部分内容已在上文中详细讨论)。


接收数据的一方,需要通过确认号(Acknowledgement Number)对已经成功接收到的数据进行确认。例如发送方发送了Seq为1234567890的数据包,有效载荷长度为5,那么接收方就需要将序列号+载荷长度进行计算,得到数字1234567895,并将此数值填入Ack号字段,返回给发送方,表示对1234567890至1234567894这一段数据(5字节数据)的确认。


在TCP协议中,确认号的取值范围为0-4296947295,和序列号取值范围一致。关于TCP的确认号,在时序图中可通过如下位置直接观察:


图1:时序图中的“确认号”

  从时序图看TCP确认号的运动规律  


理解了上述概念后,我们再来根据【序列号+载荷长度=确认号】这个公式,观察通信双方的确认号的运动规律


为了方便计算和观察,我们只取序列号中的后4位,这不会影响分析的结果和准确性。以图2为例,1号包序列号为1638701981,记作1981:


图2:时序图中的“确认号”


  • 1号包序列号尾号为1981,实际有效载荷SYN位为的1字节,因此服务器在2号包使用1981+1=1982作为确认号进行确认

  • 4号包序列号尾号为1982,实际有效载荷为138字节,因此服务器在5号包使用1985+138=2120作为确认号进行确认

  • 2号包序列号尾号为9823,实际有效载荷SYN位为的1字节,因此客户端在3号包使用9823+1=9824作为确认号进行确认

  • 6号包序列号尾号为9824,实际有效载荷为68字节,因此客户端在7号包使用9824+68=9892作为确认号进行确认。

  从时序图观察TCP累积确认机制  


RFC 793文档中的3.3 Sequence Number小节中这样写到:

The acknowledgment mechanism employed is cumulative so that an acknowledgment of sequence number X indicates that all octets up to but not including X have been received.


确认机制是累积的,因此针对序列号X的确认,表示已接收到X之前但不包括X的所有字节。


因此,TCP协议实际使用累积确认机制。这样做的好处是能在发生丢包情况时,接收方会收到不连续的数据,此时仅对接收到的连续数据部分进行确认,便于发送方发现传输中出现的丢包现象。关于丢包的相关话题,在后续文章中会详细讨论到。


另外,由于累积确认机制的存在,接收方无需针对每一个TCP包回复ACK进行确认,可以通过一个ACK包合并确认之前的所有数据包,能够节约传输成本。


对于TCP的累积确认机制,在时序图中也能有明确的展示,如图3所示:


图3:累积确认机制
在图3中,三次握手后,服务器连续发送了多个载荷长度为1460的数据包,其中13号包的序列号为3828312369,长度为1460。随后,客户端通过14号包的进行了累积确认,确认号为3828312369+1460=3828313829,这表示包括13号包在内和之前的12、11、10……4号包均被成功接收。在时序图中点击选中14号包或13号包,选中包和选中包相关的确认/被确认包,箭头均会被标记为黄色。其中粗体黄色为当前选中包,细体箭头为选中包相关的确认/被确认包。这项功能便于使用者快速找到与某一包相关的确认/被确认包。

  从时序图观察TCP累积确认机制  

和TCP确认有关的机制,还包括延迟确认机制。延迟确认机制实现了将ACK包“延迟一会儿再发送”,实现“再攒一点数据一起进行确认”的机制。在telnet或ssh这样的协议交互场景下,延迟确认机制能够有效减少TCP确认包的数量,提高交互效率。另外,延迟确认机制设计的初衷是为了避免SWS糊涂窗口综合征额外消耗CPU性能。目前,在很多操作系统中设计了关于延迟确认的实现,一般场景下的延迟确认时间为200ms。

在RFC 1122文档中,对延迟确认机制进行了这样的描述:
A host that is receiving a stream of TCP data segments can increase efficiency in both the Internet and the hosts by sending fewer than one ACK (acknowledgment) segment per data segment received; this is known as a "delayed ACK" [TCP:5].
接收 TCP 数据段流的主机可以通过发送少于每个接收数据段一个确认(ACK)段来提高互联网和主机的效率;这被称为“延迟确认”[TCP:5]。

A TCP SHOULD implement a delayed ACK, but an ACK should not be excessively delayed; in particular, the delay MUST be less than 0.5 seconds, and in a stream of full-sized segments there SHOULD be an ACK for at least every second segment.
TCP 应该实现延迟确认,但确认不应该过度延迟;特别是,延迟必须少于 0.5秒,并且在一系列全尺寸段中,至少应该每第二个段就有一个 ACK。

这里提到了两个关键信息:
1.  延迟确认时间必须少于0.5秒
2.  每收到两个全尺寸数据段,即停止延迟,直接发送ACK包

在时序图中观察延迟确认的情况,如图4所示:


图4:延迟确认机制

如图4所示,根据《从时序图看TCP-01:连接建立与三次握手》文章中描述的网络时延计算方法,可以测得客户端和服务器之间的RTT为0.25ms,这意味着确认数据所花费的时间应在0.25ms左右。

观察客户端发送4号包后,服务器间隔208ms后才响应ACK,这便是TCP的延迟确认机制在生效工作。

  一个典型的故障实例  

图5展示了一个故障网络环境的抓包,这个故障与TCP序列号和确认号有关。读者可以尝试分析该故障在流量上体现的信息。故障现象如下:

1.  使用A运营商访问网站,无法打开完整页面
2.  使用B运营商访问网站,则不存在此问题
3.  抓包显示服务器多次重传了HTTP响应,但客户端不接收,直至连接超时重置


图5:故障抓包,抓包点位于客户端

本文深入探讨了TCP的确认机制,包括确认号的计算、累积确认机制以及延迟确认机制的介绍,以及在CSNAS时序图中如何观察这些现象。通过了解这些机制和时序图的分析,能够提升流量分析工程师在工作中快速分析解决故障的能力。

免费易用的流量分析工具下载
扫码关注公众号
更多网络分析技术、技巧、干货分享


- End -

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?CSNA会员注册

×
回复

使用道具 举报

您需要登录后才可以回帖 登录 | CSNA会员注册

本版积分规则

快速回复 返回顶部 返回列表