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

  • 大多数时候都使用Z_SYNC_FLUSH调用deflate(),但间歇性地使用Z_FULL_FLUSH调用deflate()。
  • (连同数据一起)发送一个2字节的字段,该字段包含一个位,该位指示是否使用了FULL_FLUSH或SYNC_FLUSH以及一个序列号。

  • 接收者
  • 读取数据;并使用序列号来检测
    数据包已丢失。当没有数据包丢失时,2个字节为
    删除,减压正常。
  • 当检测到丢包时,接收方检查是否
    当前数据包是FULL_FLUSH或SYNC_FLUSH数据包。
  • 如果它是SYNC_FLUSH,则仅丢弃该数据包,然后继续下一个数据包。
  • 如果是FULL_FLUSH;但是,接收方将删除多余的2个字节并调用inflate()。

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

    我的第一个问题是



    我的第二个问题是

    最佳答案

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

    但是,您可以在刷新后恢复。因为在刷新后,状态才被刷新。

    因此,在丢失之后,您不想处理FULL_FLUSH数据包,因为您没有处理该数据包所必需的上下文。但是,在该数据包之后,状态已被完全刷新,因此您可以在下一个数据包中恢复充气。

    因此,您的丢包逻辑应为:

  • 等待直到收到设置了FULL_FLUSH位的数据包。
  • 等待下一个数据包。
  • 如果FULL_FLUSH数据包和此数据包之间没有数据包丢失,则从该数据包开始恢复膨胀(具有干净的上下文!)。
  • 10-04 10:36
    查看更多