一个自定义协议的应用数据需要使用校验和吗?

4
由于数据包在传输过程中的不同层上都有校验和,因此以太网和IPv4协议头部以及TCP协议甚至涵盖整个段的校验和。我知道从应用层的角度来看,即使以太网/IP/TCP的校验和是正确的,也有可能会发生损坏的数据包未被丢弃的情况,只是这种概率很低。
我正在为IM应用程序设计一种自定义的二进制协议。我的问题是,我是否需要添加校验和以确保我的应用程序数据的完整性?实际上,校验和是否真正需要呢?

1
因为以太网在整个帧上都有校验和,TCP在段上有校验和,IPv6已经放弃了IPv4所具有的头部校验和。只有您可以决定是否需要检查数据的完整性。一些应用程序会这样做,但大多数不会,并且它们似乎工作得很好。无论如何,您需要在应用程序中进行错误检测和处理,因为您可能会收到与网络本身无关的坏数据。 - Ron Maupin
是的,如果我添加校验和,那是为了错误检测。而最直观的检测错误的方法是首先检查数据的完整性,但这似乎仍然是冗余的,因为它的完整性已经由网络堆栈保证,所以我似乎可以直接使用数据。应用层中的完整性检查似乎只能将损坏的可能性从0.00000001%降低到0.000000000001%。但我仍然在想这是否有必要。 - neevek
1
正如我所写的,IETF 决定在 IPv6 的网络层中不需要校验和,因为在第二层和第四层都有校验和。 - Ron Maupin
2个回答

6
这个主题有实际的研究。它比较古老,但与当前问题非常相关。
这篇2000年的论文名为《当CRC和TCP校验和不一致时》(When the CRC and TCP checksum disagree),作者是Jonathan Stone和Craig Partridge,他们研究了数据包和帧错误,并查看了TCP校验和出错但以太网CRC没有问题的频率。您可以在此处找到PDF以下是重要部分:
从摘要中:
“过去两年的Internet数据包跟踪显示,在链路级CRC应捕获除4十亿之外的所有错误的链路上,1,100到32,000个数据包中有一个无法通过TCP校验和。”
从结论中(其中一些部分由我强调):
“在实践中,校验和被要求检测每隔几千个数据包就会发生一个错误。在排除了校验和总是捕获的那些错误之后,数据表明,平均每10十亿到每几百万个数据包中将出现一个未被检测到的错误。确切的范围取决于传输的数据类型和所经过的路径。尽管这些机会似乎很大,但它们并不鼓励自满。在每个跟踪中,一个或两个“坏苹果”主机或路径都负责大部分错误。对于那些遇到“坏苹果”主机的应用程序,接受损坏数据的预期时间可能只有几分钟。与本地I/O(例如磁盘驱动器)检测不到的错误率相比,这些率是令人不安的。我们的结论是,关键应用程序应强烈考虑使用应用程序和校验和来增强TCP校验和。”
我不知道是否有任何新的研究探讨该问题(如果您知道,请告诉我!),因此自那篇论文以来,互联网可能变得更加可靠,而论文中的数字可能不相关。
然而,这很重要:已经过去了17年,自该论文撰写以来,互联网流量量已经激增。在现在不算稀奇的1Gbps连接速度下,您每秒发送约81K个完整的TCP段,每个段有1460个字节的数据(如果数据包更小,则会发送更多)。这意味着每12.5秒发送100万个大数据包,在大约3.5小时内就会有十亿个数据包被发送(或者,如果数据包更小,则会发送更多)。

回答你的问题,这取决于具体情况。

如果是传输大文件或其他数据,如果数据本身没有受到保护,我肯定会添加额外的检查。对于消息传递,它只向网络中发送很少的数据,你可能可以仅使用TCP的校验和,并对输入进行一些合理性检查,以确保其格式正确,各种参数和字段都是有意义的。


2

因为网络中的数据包可能会出现损坏,所以我不建议使用校验和。

然而,由于您正在开发的协议可能会在公共互联网上使用,因此您需要准备处理意外应用程序向您的接收/监听端口发送UDP数据包或建立TCP连接的情况。此外,可能会有较少的端口扫描和黑客/脚本小子来攻击您的系统。

因此,您应该设计您的协议,使其易于丢弃这种类型的流量。每次传输都使用校验和是一种明智的做法。


1
你的评论很有道理,解决了我的困惑。所以添加校验和的主要原因是为了检测无效数据。我可以想象,如果我不使用校验和,仍然需要其他一些技术来检测无效数据,而校验和显然是一种简单且相对可靠的方法。 - neevek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接