Compression zlib充气错误:当接收到的数据包出现故障或丢失时,Z_数据_错误

Compression zlib充气错误:当接收到的数据包出现故障或丢失时,Z_数据_错误,compression,gzip,zlib,inflate,Compression,Gzip,Zlib,Inflate,我已经为此工作了几个星期,非常希望您的帮助!!!请原谅我的英语不好。 首先,我认为有必要描述应用场景: 我想解压什么数据?---数据来自互联网的网络流量。在这些流量中,有一些数据被gzip压缩并存储在http或tcp数据包中,如果数据量巨大且大于tcp有效负载的最大长度,则会被切片并传输。我可以从这些数据包中提取压缩数据,并通过tcp流对这些数据进行分组。因此,我可以确保从一个特定tcp流的这些数据包中提取的数据属于相同的数据源。因此,数据由许多压缩数据块组成,应用场景要求您在收到一个数据包后立

我已经为此工作了几个星期,非常希望您的帮助!!!请原谅我的英语不好。

首先,我认为有必要描述应用场景:

  • 我想解压什么数据?---数据来自互联网的网络流量。在这些流量中,有一些数据被gzip压缩并存储在http或tcp数据包中,如果数据量巨大且大于tcp有效负载的最大长度,则会被切片并传输。我可以从这些数据包中提取压缩数据,并通过tcp流对这些数据进行分组。因此,我可以确保从一个特定tcp流的这些数据包中提取的数据属于相同的数据源。因此,数据由许多压缩数据块组成,应用场景要求您在收到一个数据包后立即解压缩数据。对于每个tcp流,我们维护一个z_流数据结构。
  • 程序何时报告错误----所有错误都是“Z_DATA_error:无效距离太远”。然后我发现当收到的数据包出现故障或某些数据包丢失时,就会发生错误 一个简单的例子:

    压缩数据被分成多个数据块并存储在网络数据包(p1、p2、p3、p4、p5、p6、p7)中,然后在一个特定的tcp流中传输对于每个tcp流,我们都维护一个z_流数据结构。显然,p1包括gzip头0x1f 0x8b 0x08…,但由于网络传输的不确定性,接收到的数据包可能出现故障或丢失,例如:(p1、p2、p5、p6、p7、p3、p4),前两个数据包可以正常解压,但是当解压缩p5时,会发生错误(Z_DATA_error)

    所以,我有这些问题:

  • 由于应用场景的原因,我需要在收到一个带有gzip内容编码的数据包后解压缩数据。所以我想知道ZLIB是否支持这样的函数--<强>直接解压缩一个压缩块而不必考虑数据包的到达顺序?< /强>
  • 我还测试了数据包接收顺序的影响:如果我按原始顺序对数据排序,然后按顺序解压,它将正常解压
  • 第三,从逻辑上讲,对于打包的接收顺序(p1、p2、p5、p6、p7、p3、p4),当依次解压缩这些数据包时,p1、p2将成功解压缩,p5、p6、p7将解压缩失败,下一个接收到的数据包是p3,从逻辑上讲,它应该成功解压缩,但当我测试这个案例时,它失败了,我不明白
  • 我还发现了一个不常见的令人困惑的问题:如果我将数据包排序为(p1、p2、p3、p5、p4…),从逻辑上讲,当解压缩p5时,它应该报告一个错误,但如果它成功解压缩,我不理解这一点

    以下是源代码:

  • 
    /**
    *buf:从tcp数据包中提取的gzip压缩数据
    */
    void dowithGzipDataByZlib(z_stream*p_zlib_strm,unsigned char*buf,int buflen)
    {
    int zlib_status=Z_OK;
    int bytes\u dc\u now=0;
    无符号字符pNowResBuff[4096];
    printf(“----\n”);
    (*p_zlib_strm).avail_in=buflen;
    (*p_zlib_strm)。下一步=buf;
    做{
    memset(pNowResBuff,04096);
    (*p_zlib_strm).avail_out=4096;
    (*p_zlib_strm)。下一个输出=pNowResBuff;
    zlib_状态=充气(p_zlib_strm,Z_NO_冲洗);
    printf(“充气状态:%d\n”,zlib\u状态);
    如果(Z_确定!=zlib_状态和&Z_流结束!=zlib_状态){
    printf((*p\u zlib\u strm).avail\u in:%d\n“,(*p\u zlib\u strm).avail\u in);
    printf(“错误消息:%s\n”,p\u zlib\u strm->msg);
    返回;
    }
    字节现在=4096-(*p\u zlib\u strm);
    //printf(“字节\u dc\u编号:”)
    }而(0==(*p_zlib_strm).avail_out);
    printf((*p\u zlib\u strm).avail\u in:%d\n“,(*p\u zlib\u strm).avail\u in);
    }
    //在dirpath下,有一些从一个特定tcp流的数据包中提取的压缩数据,并将它们存储在“file\u basename\u%d”文件中。(%d是接收订单编号:1,2,3,4…)
    无效读取(char*dirpath,char*file\u basename)
    {
    char文件列表[99][255];
    int file_count=listDir(dirpath,filelist,99255);
    char文件路径[255];
    z_流zlib_strm={0};
    zlib_strm.zalloc=Z_NULL;
    zlib_strm.zfree=Z_NULL;
    zlib_strm.opaque=Z_NULL;
    zlib_strm.next_in=Z_NULL;
    zlib_strm.avail_in=0;
    燃烧剂2(&zlib|strm,32 | MAX|WBITS);
    文件*fp;
    char-buf[2048];
    //sort_file_ind:数组存储压缩数据的原始顺序。
    int sort_file_ind[99]={0,1,2,3,15,16,17,18,19,20,21,4,5,6,7,8,9,10,11,12,13,14};
    对于(int i=1;i