2

我正在开发一个客户端服务器应用程序,其中客户端压缩发送到服务器的 2MB 数据,服务器接收数据将其解压缩并将其写入文件。

对于某些数据包解压缩失败,我将 MD5 和添加到客户端和服务器端代码,并在压缩数据后在客户端使用解压缩进行调试。在客户端传递给解压缩函数的相同参数在服务器端失败并出现 Z_DATA_ERROR。数据的 MD5sum 似乎相同。我完全不知道接下来我能做什么。

服务器端鳕鱼看起来像这样:

int ret = uncompress((Bytef*)unCompressedBuffer, &dwUncompressedBytes, (const Bytef*) receivedBuffer+525, dwBlockLength);

    if (ret == Z_OK)
    {

    }
    else
    {

        std::cout << " Uncompression failed for Block: " << iBlock << std::endl;

        std::cout << " PacketType: 4" << " Block Number:" << iBlock << " Length:" << dwBlockLength << "Error:" << ret << std::endl;

        PrintMD5SumResult((PBYTE)receivedBuffer+525, compressedSize-525);
        std::cout << " Uncompressed MD5 Checksum:0";
        PrintMD5SumResult((PBYTE)unCompressedBuffer, dwUncompressedBytes);

        }
}

客户端代码如下所示:

int ret = compress2(l_pCompressData + 4, &destLen, 
        (const Bytef*) pBlockData, dwBlockSize, 6); 

memcpy(m_pWriteBuffer+525, l_pCompressData, destLen);
    m_dwWriteBytes = destLen+525;

std::cout << " \n Compressed MD5 Sum:0";
PrintMD5SumResult(m_pWriteBuffer, m_dwWriteBytes);
PrintMD5SumResult(m_pWriteBuffer+525, m_dwWriteBytes-525);

int ret = uncompress(m_pUnCompressData, &uncomLen, (const Bytef*)m_pWriteBuffer+525, destLen);

if(ret != Z_OK)
{
    std::cout << " Uncompression has failed." << std::endl;
}
else
{
    //std::cout << " UnCompressed MD5 Sum:0";
    //PrintMD5SumResult((PBYTE)m_pUnCompressData, md5Output, dwBlockSize);
}

// Write the 2MB to the network
WriteDataOverNetwork(m_NetworkStream, m_pWriteBuffer, m_dwWriteBytes, &dwNumBytes, TRUE);

我将问题缩小到 zlib 中的以下代码段 - 但很难理解它。在 inflate() 函数中,(ZSWAP32(hold)) != state->check) 此语句失败。有人可以帮我吗?此处使用的 MD5sum 来自 Boton C++ 库。

    case CHECK:
            if (state->wrap) {
                NEEDBITS(32);
                out -= left;
                strm->total_out += out;
                state->total += out;
                if (out)
                    strm->adler = state->check =
                        UPDATE(state->check, put - out, out);
                out = left;
                if ((
#ifdef GUNZIP
                     state->flags ? hold :
#endif
                     ZSWAP32(hold)) != state->check) {
                    strm->msg = (char *)"incorrect data check";
                    state->mode = BAD;
                    break;
                }
4

3 回答 3

0

我最近在使用 zlib 进行内存压缩/解压缩时也遇到了这个问题。代码如下:

size_t size = 1048576;
void *data;
void *comp_data;
uLong comp_data_len;
void *uncomp_data;
uLong uncomp_data_len;
void *temp;
int ret;

data = calloc(1, size); // data is filled with all zeros

comp_data_len = size * 1.01 + 12;
comp_data = calloc(1, size);
ret = compress(comp_data, &comp_data_len, data, size); //here ret is Z_OK.

uncomp_data_len = size;
uncomp_data = calloc(1, uncomp_data_len);
ret = uncompress(uncomp_data, &uncomp_data_len, comp_data, comp_data_len); //here ret is Z_OK

temp = calloc(1, 496);

for (i = 0; i < 100; i++)
{
    //here fill some random data to temp

    memcpy((char*)data + i * 100, temp, 496);

    ret = compress(comp_data, &comp_data_len, data, size); //here ret is Z_OK.
    ret = uncompress(uncomp_data, &uncomp_data_len, comp_data, comp_data_len); //here ret sometimes is Z_OK, sometimes is Z_DATA_ERROR!!!
}

我还跟踪了代码,发现它在语句“inflate() function, (ZSWAP32(hold)) != state->check)”处也失败了。所以我不敢相信 uncompress 函数与数据模式有关。我错了吗?

我也注意到compress函数调用deflate进行压缩,deflate每64k处理一次数据,所以需要我将它拆分为64k块,逐块压缩,然后uncompress可以正常工作吗?

于 2013-06-05T13:45:47.283 回答
-1

不知道是不是正确的答案,也许有帮助!我的英语太差了,希望你能理解。也许参数转换为另一个有错误。当他们转换信息时可能会丢失!我遇到了同样的问题,使用源代码类型后问题已经解决(Bytef\uLongf\uLong等)。wed 是中文的,你可以用谷歌翻译。 http://www.360doc.com/content/13/0927/18/11217914_317498849.shtml

于 2013-09-27T11:17:12.457 回答
-1

这是我的测试。arry[]可以更大,同时sour[]/dest[]/destLen/Len会改变。使用源代码类型问题已经解决。希望会有所帮助。

我的代码如下:

    #include <stdio.h>
    #include "zlib.h"

    int main(){
        //the buffer can be larger
    Bytef arry[] = "中文测试 yesaaaaa bbbbb ccccc ddddd 中文测试 yesaaaaa bbbbb ccccc ddddd 中文测试yesaaaaa bbbbb ccccc ddddd 中文测试 yes 我是一名军人!";
    //buffer length
        int size = sizeof(arry);
    //store the uncompressed data
        Bytef sour[2500];
        //store the compressed data
    Bytef dest[2500];
        //压缩后的数据可能比源数据要大
    unsigned long destLen = 2500;
        //解压数据时因为不知道源数据大小,设置时长度尽可能大一些。以免出错
    unsigned long Len = 2500;
    int ret = -1;
    ret = compress(dest,&destLen,arry,size);
    //dest[destLen] = '\0';
    printf("ret = %d\ndest = %s\n", ret, dest);
    ret = uncompress(sour,&Len,dest,destLen);
    //sour[size-1] = '\0';
    printf("ret = %d\nsour = %s\n", ret, sour);
    return 0;
}
于 2013-09-30T02:05:37.043 回答