使用TCP时是否需要使用校验和来保护消息?

时间:2021-01-18 03:59:38

Using TCP as the network protocol, I prefix the size (and potentially checksum?) of each message before sending the message through the wire. I'd like to know, does it make sense to calculate and transmit the checksum of the message, to ensure that the message will be delivered (if and when it will be delivered) unchanged, e.g. because of some network error. Currently I'm sending 4-byte size + 2-byte checksum (CRC-16) of the message, before sending the message itself. The other endpoint correctly identifies expected message length, reads it, and validates the checksum.

使用TCP作为网络协议,在通过网络发送消息之前,我在每个消息的大小(以及潜在的校验和)上加上前缀。我想知道,计算和传输消息的校验和是否有意义,以确保消息不会被传递(如果和何时会被传递),例如,由于一些网络错误。目前,我正在发送消息的4字节大小+ 2字节校验和(CRC-16),然后再发送消息本身。另一个端点正确地标识预期的消息长度,读取它,并验证校验和。

I know that TCP has internal packet validation mechanism, and I have a strong feeling that my message validation at application level is redundant, but I'm not sure and need your advice before I make a decision.

我知道TCP有内部的包验证机制,我有强烈的感觉,我在应用程序级别的消息验证是多余的,但是我不确定,在做决定之前需要您的建议。

I'm in the process of developing the client-server application, with tens of thousands potential connections to the server daily. Even a single damaged byte in any of the messages might cause whole chain of incorrect messages exchanged, which is unacceptable (well, almost all client-server applications have the same requirements, don't they). So I want to be sure - can I safely trust TCP's internal reliability, or is it better to provide my own checksum validation mechanism. And I'm talking about small, two byte checksums (CRC-16), I'm not talking about digitally signing messages, etc. (And the system is developed in .Net (C#) using sockets, if that makes any difference).

我正在开发客户端-服务器应用程序,每天有成千上万的潜在连接到服务器。即使任何消息中的一个字节受损,也可能导致交换的整个错误消息链,这是不可接受的(几乎所有客户机-服务器应用程序都有相同的要求,不是吗?)因此,我想确定的是——我是否可以安全地信任TCP的内部可靠性,还是最好提供我自己的校验和验证机制。我说的是小的、两个字节的校验和(CRC-16),我说的不是数字签名消息,等等(这个系统是在。net (c#)中开发的,使用套接字,如果有什么区别的话)。

3 个解决方案

#1


2  

According to this paper "the checksum will fail to detect errors for roughly 1 in 16 million to 10 billion packets". Assuming a packet size of 1024 bytes, this amounts to one undetected error every 16 GB to 10 TB of network traffic.

根据这篇论文“校验和将不能检测大约1 / 1600到100亿个数据包的错误”。假设数据包大小为1024字节,那么每16gb到10tb的网络流量就会出现一个未检测到的错误。

Many protocols like HTTP, FTP, SMTP and probably many more rely on the checksums in the underlying layers. It is my belief that this practice is questionable given the above numbers.

许多协议,比如HTTP、FTP、SMTP,可能还有更多的协议,都依赖于底层的校验和。鉴于上述数字,我认为这种做法是有问题的。

Sidenote: The same is true for hard drives as well. Typical desktop drives have an error detection capability of 1 bit in 10 TB read. Read your 2 TB disk 5 times and on average you will suffer one incident of corruption.

Sidenote:同样适用于硬盘驱动器。典型的桌面驱动器在10 TB读取中有1比特的错误检测能力。阅读你的2 TB磁盘5次,平均你将会遭受一次腐败事件。

To answer your question: if your tolerance for very rare, spurious failures is medium to high, don't bother checksumming. If you can't tolerate any corruption, add a checksum to your protocol.

回答你的问题:如果你对非常罕见的、虚假的失败的容忍度是中等到高的,不要费事去校验和。如果您不能容忍任何腐败,请向您的协议添加一个校验和。

#2


1  

As far as TCP is concerned, like others have pointed out, it is not 100% reliable and some messages can get corrupt during transmission.

就TCP而言,就像其他人指出的那样,它不是100%可靠的,一些消息在传输过程中可能会损坏。

To keep integrity of messages you will have to use CRC at the application level.

为了保持消息的完整性,您必须在应用程序级别上使用CRC。

However, if you are using SSL/TLS then you do not have to do CRC at the application level as it is already done. Messages exchanged over SSL/TLS are checked for integrity by the libraries. Almost all of the algorithms in SSL/TLS cipher suite perform message authentication. To know which algorithms does HMAC or doesn't or have more reliable one you have to see its name. The algorithm names have three parts. For example,

但是,如果您正在使用SSL/TLS,那么您不必在应用程序级别上执行CRC,因为已经这样做了。通过SSL/TLS交换的消息由库检查其完整性。SSL/TLS密码套件中的几乎所有算法都执行消息身份验证。要知道哪种算法是HMAC的,或者没有,或者有更可靠的算法,你必须看到它的名字。算法名称有三个部分。例如,

  "TLS_RSA_WITH_AES_256_GCM_SHA384" has following three parts;

  TSL_RSA     => Asymmetric algorithm for key exchange during initial handshake.
  AES_256_GCM => Symmetric algorithm for message encryption.
  SHA384      => HMAC for message integrity.

So in the above SSL/TLS algorithm the SHA384 is used for message authentication and that is why you do not have to do CRC in your application.

因此,在上面的SSL/TLS算法中,SHA384用于消息身份验证,这就是为什么您不必在应用程序中执行CRC。

#3


0  

TCP does not guarantee 100% that your data will be transferred and received the way it was sent.

TCP不能100%保证您的数据将按照发送的方式传输和接收。

It is always a chance that your message 3_ABC with CRC 42 will accidentally be converted to 10_FU@0Ээ^+Ъr with the same CRC. However, you still should rely on it.

总是一个机会,你的信息3 _abc CRC 42意外将转换为10 _fu@0Ээ^ +Ъr CRC相同。然而,你仍然应该依靠它。

Since the TCP, as you have already found out, simply sends the checksum of each packet and compares it to the content on the other side, you do not to have to do it on your own. TCP also guarantees that data comes in the order it was sent, so if you stick to the pattern [from 4 to 8 bytes of message's length + message itself] that should be enough.

由于TCP,正如您已经发现的,只需发送每个数据包的校验和,并将其与另一端的内容进行比较,您就不必自己去做了。TCP还保证数据按发送的顺序到达,所以如果您坚持使用模式(从消息长度的4到8字节+消息本身),就应该足够了。

However, in the case you are using the message pattern, you might go into using the UDP instead. There are some ways to achive maximum network potentian exactly with UDP, not TCP. One of them is Lidgren.Network C# library which can send packets in multiple kinds of reliability and order.

然而,在使用消息模式的情况下,您可以转而使用UDP。有一些方法可以实现最大的网络潜力和UDP,而不是TCP。其中之一是利德格伦。网络c#库,可以以多种可靠性和顺序发送数据包。

#1


2  

According to this paper "the checksum will fail to detect errors for roughly 1 in 16 million to 10 billion packets". Assuming a packet size of 1024 bytes, this amounts to one undetected error every 16 GB to 10 TB of network traffic.

根据这篇论文“校验和将不能检测大约1 / 1600到100亿个数据包的错误”。假设数据包大小为1024字节,那么每16gb到10tb的网络流量就会出现一个未检测到的错误。

Many protocols like HTTP, FTP, SMTP and probably many more rely on the checksums in the underlying layers. It is my belief that this practice is questionable given the above numbers.

许多协议,比如HTTP、FTP、SMTP,可能还有更多的协议,都依赖于底层的校验和。鉴于上述数字,我认为这种做法是有问题的。

Sidenote: The same is true for hard drives as well. Typical desktop drives have an error detection capability of 1 bit in 10 TB read. Read your 2 TB disk 5 times and on average you will suffer one incident of corruption.

Sidenote:同样适用于硬盘驱动器。典型的桌面驱动器在10 TB读取中有1比特的错误检测能力。阅读你的2 TB磁盘5次,平均你将会遭受一次腐败事件。

To answer your question: if your tolerance for very rare, spurious failures is medium to high, don't bother checksumming. If you can't tolerate any corruption, add a checksum to your protocol.

回答你的问题:如果你对非常罕见的、虚假的失败的容忍度是中等到高的,不要费事去校验和。如果您不能容忍任何腐败,请向您的协议添加一个校验和。

#2


1  

As far as TCP is concerned, like others have pointed out, it is not 100% reliable and some messages can get corrupt during transmission.

就TCP而言,就像其他人指出的那样,它不是100%可靠的,一些消息在传输过程中可能会损坏。

To keep integrity of messages you will have to use CRC at the application level.

为了保持消息的完整性,您必须在应用程序级别上使用CRC。

However, if you are using SSL/TLS then you do not have to do CRC at the application level as it is already done. Messages exchanged over SSL/TLS are checked for integrity by the libraries. Almost all of the algorithms in SSL/TLS cipher suite perform message authentication. To know which algorithms does HMAC or doesn't or have more reliable one you have to see its name. The algorithm names have three parts. For example,

但是,如果您正在使用SSL/TLS,那么您不必在应用程序级别上执行CRC,因为已经这样做了。通过SSL/TLS交换的消息由库检查其完整性。SSL/TLS密码套件中的几乎所有算法都执行消息身份验证。要知道哪种算法是HMAC的,或者没有,或者有更可靠的算法,你必须看到它的名字。算法名称有三个部分。例如,

  "TLS_RSA_WITH_AES_256_GCM_SHA384" has following three parts;

  TSL_RSA     => Asymmetric algorithm for key exchange during initial handshake.
  AES_256_GCM => Symmetric algorithm for message encryption.
  SHA384      => HMAC for message integrity.

So in the above SSL/TLS algorithm the SHA384 is used for message authentication and that is why you do not have to do CRC in your application.

因此,在上面的SSL/TLS算法中,SHA384用于消息身份验证,这就是为什么您不必在应用程序中执行CRC。

#3


0  

TCP does not guarantee 100% that your data will be transferred and received the way it was sent.

TCP不能100%保证您的数据将按照发送的方式传输和接收。

It is always a chance that your message 3_ABC with CRC 42 will accidentally be converted to 10_FU@0Ээ^+Ъr with the same CRC. However, you still should rely on it.

总是一个机会,你的信息3 _abc CRC 42意外将转换为10 _fu@0Ээ^ +Ъr CRC相同。然而,你仍然应该依靠它。

Since the TCP, as you have already found out, simply sends the checksum of each packet and compares it to the content on the other side, you do not to have to do it on your own. TCP also guarantees that data comes in the order it was sent, so if you stick to the pattern [from 4 to 8 bytes of message's length + message itself] that should be enough.

由于TCP,正如您已经发现的,只需发送每个数据包的校验和,并将其与另一端的内容进行比较,您就不必自己去做了。TCP还保证数据按发送的顺序到达,所以如果您坚持使用模式(从消息长度的4到8字节+消息本身),就应该足够了。

However, in the case you are using the message pattern, you might go into using the UDP instead. There are some ways to achive maximum network potentian exactly with UDP, not TCP. One of them is Lidgren.Network C# library which can send packets in multiple kinds of reliability and order.

然而,在使用消息模式的情况下,您可以转而使用UDP。有一些方法可以实现最大的网络潜力和UDP,而不是TCP。其中之一是利德格伦。网络c#库,可以以多种可靠性和顺序发送数据包。