TCP 的确认并不能保证数据已经被传送

网络工程 通讯协议 协议理论 传输协议 第4层 射频卡
2021-07-05 17:24:07

在 RFC 793 中有一部分是关于 TCP 段的确认:

当 TCP 传输一个包含数据的段时,它会在重传队列中放置一个副本并启动一个计时器;当收到对该数据的确认时,该段将从队列中删除。如果在定时器用完之前没有收到确认,则重新传输该段。

TCP 的确认并不能保证数据已交付给最终用户,而仅保证接收方 TCP 已对此负责。

现在,这很有趣。在我们的 NOC 中,我们经常对我们的网络和外部客户端网络之间的连接问题进行故障排除,每当我们在防火墙上嗅探流量并看到双向发送和接收的 SYN 和 ACK 位时,我们假设连接已建立并且问题与此无关用网络做。

但是现在这个 RFC 让我思考 - 如果 TCP 连接已建立但用户仍然遇到连接问题,我还应该检查什么(不设置 Wireshark)?

3个回答

RFC 的这一部分是关于将责任移交给操作系统或流程的下一阶段。它从根本上关注层的分离。

TCP 的确认并不能保证数据已交付给最终用户,而只能保证接收方 TCP 已对此负责。

我一直是这样想的:

  • 操作系统可能会在发送 ACK 和数据到达客户端进程之间崩溃(这里的“客户端”是指操作系统的客户端,而不是“网络客户端”)
  • 客户端进程可能有问题或崩溃,或者只是比预期慢得多来处理传入的数据,或者实际上只在不明显的情况下读取它
  • 如果客户端正在向前发送数据,可能是发送到磁盘文件,则该文件可能尚未写入或刷新
  • 如果客户端正在通过 TCP 向前发送数据,则远端 TCP 可能没有传输数据,接收到 ACK,或者远端进程成功消费了数据

它只是说这是第 3 层确认(“我听到你的字节”)而不是更高层的确认。例如,考虑 TCP ACK、250 OK下一跳邮件网关接受消息后的 SMTP 、消息接收消息(例如,根据RFC 3798)、消息打开跟踪像素、来自 PA 的感谢信、和回复说“是的,我会做的。”

另一个具体的例子是打印机:

  • 它必须在知道数据的结尾包含什么之前尽早 ACK 数据(可能是一个 Postscript 文件,其中包含的库比 TCP 传输窗口大)
  • 它可能包含一个状态查询(“你有纸吗?”,它显然可以执行)
  • 它可能包含一个打印命令(“请打印这个”,如果缺纸,它可能会失败)

我建议,如果用户看到并发送 ACK 但仍然遇到连接问题,那么拥塞、操作系统或应用程序问题的可能性比任何严格的网络相关问题都要高几个数量级。

为了诊断,我建议寻找重传,而不是专门的 ACK。

从 RFC 的角度来看,“最终用户”是应用程序。不能保证应用程序得到了数据,只是 TCP 进程收到了它。

从您的 NOC 的角度来看,网络正在运行并且数据已到达终端主机。想必,这就是你关心的全部。

你可以这样看。

你是 M.Smith,你想给 M.Toto 发一封信(人是应用层)。

要发送这封信,您需要前往当地邮局 A,后者会将信件发送到 M.Toto 当地邮局 B(邮局是 TCP 层)。

邮局 A 和邮局 B - B 会向邮局 A 发送一个 ACK​​。但是没有什么可以保证信件会到达 M.Toto。邮局 B 和 M.Toto 之间可能发生任何事情。

这基本上就是RFC所说的。