c++ - zlib inflate() 和网络链接上的数据丢失

标签 c++ zlib

我有 2 个通过网络链接进行通信的应用程序。发送方将使用 zlib 的 deflate() 压缩数据包并通过网络发送。然后接收器将使用 inflate() 解压缩数据。网络链路上的数据包可能会丢失;为了最大限度地减少解压错误,我实现了以下方法:
发件人

  1. 大部分时间都使用 Z_SYNC_FLUSH 调用 deflate(),但间歇性地使用 Z_FULL_FLUSH 调用 deflate()。

  2. 发送(与数据一起)一个 2 字节字段,其中包含一个指示是否使用 FULL_FLUSH 或 SYNC_FLUSH 的位以及一个序列号。

接收者

  1. 读入数据;并使用序列号检测是否 数据包已丢失。当没有数据包丢失时,2个字节是 删除后解压正常。
  2. 当检测到数据包丢失时,接收方检查是否 当前数据包是 FULL_FLUSH 或 SYNC_FLUSH 数据包。

    • 如果是 SYNC_FLUSH,则数据包将被简单地丢弃,我们将继续处理下一个数据包。

    • 如果是 FULL_FLUSH;然而,接收方会删除多余的 2 个字节并调用 inflate()。

这在 99% 的情况下都有效;从某种意义上说,inflate() 成功,并且未压缩的数据确实与发送者压缩之前的数据相同。这是我的期望!
偶尔;然而,这种方法使接收器处于不良状态,其中每个后续数据包(包括 FULL_FLUSH 数据包)都无法解压缩。 inflate() 返回 Z_DATA_ERROR 并且 zlibContext.zstream.msg 包含“错误的 header 检查”;尽管我偶尔会收到“无效距离太远”的消息。

我的第一个问题是

Should I expect to recover and inflate() successfully when the packet at hand was compressed using a FULL_FLUSH flush mode; even if previous packets were lost? For example, sender compresses using deflate(ctx, SYNC_FLUSH) the first 3 packets and sends them; one at a time, over the network. The sender then compresses the fourth packet using deflate(ctx, FULL_FLUSH) and sends it across the network. The receiver receives packet 1 & 2 and calls inflate() with success. The receiver then receives packet 4; it detects (via the sequence #) that it has missed packet 3. Since packet 4 was compressed using a FULL_FLUSH, the receiver expects that the inflate() will successfully decompress the packet. Is this a valid assumption?

我的第二个问题是

Is there anything else I need to do in in the receiver to be able recover from packet loss and continue decompressing packets?

最佳答案

你的逻辑有点错误。 FULL_FLUSH 数据包进行完全刷新。在该数据包之后,状态将被刷新。通过处理FULL_FLUSH数据包,您正在尝试执行刷新 - 但您不能,因为您没有正确的状态来执行刷新。

但是,您可以在刷新后继续。因为刷新之后,状态就被刷新了。

因此,在丢失后,您不想处理FULL_FLUSH数据包,因为您没有处理它所需的上下文。但是,在该数据包之后,状态已完全刷新,因此您可以使用下一个数据包恢复通货膨胀。

所以你的丢包逻辑应该是:

  1. 等待,直到收到设置了 FULL_FLUSH 位的数据包。
  2. 等待下一个数据包。
  3. 如果 FULL_FLUSH 数据包和此数据包之间没有丢失数据包,则从此数据包开始恢复膨胀(使用干净的上下文!)。

关于c++ - zlib inflate() 和网络链接上的数据丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39171580/

相关文章:

css - GZIP CSS 完全破坏页面

Java:如何恢复使用 python 的 zlib 编码器压缩的字符串数据

c++ - 大型代码库的代码标准重构

c++ - 结构体中的动态数组长度

c++ - 尾随返回类型语法样式是否应该成为新 C++11 程序的默认值?

python - 如何在json中转储压缩字符串?

php - 为PHP 5.6静态编译Zlib

c++ - 如何将二进制数据写入压缩文件

c++ - 获取非实例化结构的地址

java - 欧拉计划 N# 8 JAVA