2017-04-06 163 views
1

我正在使用zlib,並且解壓縮時遇到了一些問題。我嘗試解壓縮到我的程序中的數據包,但只有第一個數據包能夠正確解除分解。例如:Zlib解壓縮C++

//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初始化decompresor,30但沒有help.How我能解決這個問題? 代碼示例:

//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

顯示您的代碼。我們還能怎樣幫助? –

+1

如果你在一個步驟中進行壓縮,你應該緩衝你的數據包並且在一個步驟中對它們進行解壓縮,或者你應該對所有的數據包使用一個解壓縮器,因爲解壓縮的字節沒有跟隨壓縮流中的字節邊界。沒有一些代碼我不能給你更具體的建議。 – gabry

+0

我加了我的代碼 – rooltex

回答

1

這裏發生的是,發件人沖洗用空存儲塊放氣壓縮機,以產生一個解壓縮包,然後刪除最後四個字節空的存儲塊,期待你,接收者,插入。

所以你需要做的是在壓縮的數據包之間插入字節00 00 ff ff,然後將整個東西解壓爲一個zlib流。不要爲第二個數據包初始化充氣 - 只需將壓縮數據輸入充氣機(包括插入的字節)。

+0

謝謝,它幫助了!!!!! – rooltex