【问题标题】:Zlib Inflate data from http packetZlib 从 http 数据包膨胀数据
【发布时间】:2013-10-24 20:34:48
【问题描述】:

我正在尝试使用 zlib 的 inflate 来解压缩我从 http 数据包中收到的一些数据。

数据包如下:

数据包本身说它是用 gzip 编码的,所以我认为它应该可以工作。但是,当我通过 inflate 函数运行数据时,我得到“无效的块类型”。需要说明的是,我只是将数据包的突出显示部分传递给了 inflate 函数。我错过了什么?

这是我用来解压数据的代码:

int Decompress(const u_char* strStreamIn, int nStreamInLen, u_char* strStreamOut)
{
  int ret = -1;
  int err = -1;

  z_stream strm  = {0};
  strm.total_in  = strm.avail_in  = nStreamInLen;
  strm.total_out = strm.avail_out = nStreamInLen * 6;
  strm.next_in   = (Bytef*) strStreamIn;
  strm.next_out  = (Bytef*) strStreamOut;
  strm.zalloc    = Z_NULL;
  strm.zfree     = Z_NULL;
  strm.opaque    = Z_NULL;

  err = inflateInit2(&strm, -MAX_WBITS);
  if (err == Z_OK) {
    err = inflate(&strm, Z_FINISH);
    if (err == Z_STREAM_END) {
      ret = strm.total_out;
    }
    else {
      inflateEnd(&strm);
      return err;
    }
  }
  else {
    inflateEnd(&strm);
    return err;
  }
  inflateEnd(&strm);
  return ret;  
}

【问题讨论】:

  • 根据this postthis post,我应该使用:inflateInit2(&strm, 16+MAX_WBITS); 但即使我这样做,我也会得到“设置了未知的标头标志”。

标签: http gzip zlib


【解决方案1】:

是的,需要使用inflateInit2(),第二个参数为31,请求gzip解压。如果您将其输入1f 8b 08 00 ...,那么您将不会得到“设置了未知的标头标志”。那一定不是你在做什么。

顺便说一句,将total_intotal_out 设置在你设置的位置没有任何作用,因为inflateInit[2]() 将它们设置为零。将它们设置为您在有效位置所做的值,例如在inflateInit之后,也没有任何意义。

avail_out 设置为输入大小的六倍是一种猜测,并不总是足够的。如果这还不够,那么您将收到Z_FINISH 的错误。您应该使用循环调用inflate() 处理输入并产生输出所需的次数。

我建议你阅读zlib.h,然后阅读how to use zlib

【讨论】:

  • 马克,感谢您确认我的代码(大部分)正确,在采纳您的建议并仔细查看我传入的数据后,我发现了问题。我编写的一个函数中存在一个错误,它将一个缓冲区复制到另一个缓冲区。我还删除了total_intotal_out 的初始化。我将 avail_out 设置为输入的 6 倍,只是为了让函数正常工作。我现在要修复它以更准确。感谢您的所有帮助!
猜你喜欢
  • 2014-07-25
  • 1970-01-01
  • 1970-01-01
  • 2013-07-15
  • 2021-03-01
  • 2013-06-05
  • 1970-01-01
  • 2021-05-19
  • 1970-01-01
相关资源
最近更新 更多