Zlib解压缩c ++

时间:2017-04-06 09:36:01

标签: c++ compression zlib deflate inflate

我正在使用zlib并且在解压缩方面遇到了一些问题。我尝试解压缩来到我的程序的数据包,但只有第一个数据包被正确解压缩。例如:

    //first compressed packet    
        78 5e 72 65 60 08 65 bf cd c0 60 28 98 3f 95 03
        08 18 19 19 25 18 4c af b9 32 38 0a a4 d6 6c 6d
        6c 60 60 04 42 20 60 31 2b c9 37 61 c9 2c 28 33
        e3 cc cd 4c 2e ca 2f ce 4f 2b 61 4e ce cf 65 00
        29 38 c0 03 51 c6 7c 9b 81 e5 40 44 32 23 00
    //first decompressed packet
    //inflate return 0
        45 00 00 55 07 db 00 00 31 11 6f 95 08 08 08 08 
        01 01 01 18 00 35 d6 45 00 41 10 65 7c b5 81 80 
        00 01 00 01 00 00 00 00 04 36 74 6f 34 04 69 70 
        76 36 09 6d 69 63 72 6f 73 6f 66 74 03 63 6f 6d 
        00 00 01 00 01 c0 0c 00 01 00 01 00 00 03 db 00 
        04 c0 58 63 01 

但是,当我尝试解压缩第二个数据包"膨胀"函数返回-3并解压缩。第二个压缩包的示例:

  //second compressed packet
  //inflate return -3
  72 65 60 f0 62 bf 03 36 74 3e c2 d0 77 cb 19 cc
  de cc d8 18 8c 30 94 b9 20 b1 92 35 33 bf 38 b1
  84 a9 a8 14 c5 24 17 2f 06 96 88 63 e7 ad 01 00

我尝试用参数MAX_WBITS,-MAX_WBITS,30来初始化解压缩器,但它没有用。我怎么能解决这个问题? 代码示例:

//functions
    InitZDecompressor = ( int (WINAPI *)( z_stream_s*, int,const char*,int)) GetProcAddress(zlibdll,"inflateInit2_");
    ZDecompressor = (int (WINAPI *)(z_stream_s*,int)) GetProcAddress(zlibdll,"inflate");
    ResetZDecompressor = (int (WINAPI *)(z_stream_s*)) GetProcAddress(zlibdll,"inflateEnd");

//initialize
__int32 Decoder(unsigned __int8* PDU, unsigned __int32 size, unsigned __int8 * out_b, z_stream_s & stream, bool & IsInit)
{
    if (IsDllLoaded == false || PDU == nullptr) { return 0; }//if Zlib DLL was not loaded, or incoming packet is not cTCP    

    if ( !IsInit )
    {
        SecureZeroMemory(&stream, sizeof(stream));
        auto res = InitZDecompressor( &stream, MAX_WBITS , "1.2.11", sizeof(z_stream_s));//initialize only one time
        IsInit = true;
    }

    stream.next_in = PDU;
    stream.avail_in = size;
    stream.next_out = out_b;
    stream.avail_out = 1048576;
    stream.total_out = 0;

    __int32 ret = 0;
//inflate
    while ( stream.avail_in && ret == 0  )
    { 
        ret = ZDecompressor(&stream, 2);
    }
    return ret;
}
//inflateEnd
void ResetDecompessor(bool & isInit, z_stream_s & stream)
{
    if (isInit){ 

        ResetZDecompressor(&stream);
        isInit = false;
        memset(&stream, 0 ,sizeof(stream));
    }
}
//test func
void testZlib(unsigned __int8 *StPt, __int64 size,z_stream_s & stream,bool & isInit)
{
// StPt - start of compressed data
//size - size of compressed data
//isInit - is zStream already initialize

    unsigned __int8 * OutBuf = new unsigned __int8[ 1048576 ];

    auto res = zlib->Decoder( StPt,size, OutBuf, stream, isInit );

    delete [] OutBuf;
}

1 个答案:

答案 0 :(得分:1)

这里发生的是发送方正在使用空的存储块刷新deflate压缩器以生成可解压缩的数据包,然后删除空存储块的最后四个字节,期待你,接收器,插入它。

所以你需要做的是在压缩包之间插入字节00 00 ff ff,然后将整个内容解压缩为一个zlib流。不要为第二个数据包初始化膨胀 - 只需将压缩数据输入充气机(包括插入的字节)。