我正在研究客户端服务器应用程序,其中客户端压缩发送到服务器的2MB数据,服务器接收数据解压缩并将其写入文件。
对于某些数据包,解压缩失败,我将MD5总和添加到客户端和服务器端代码,并在压缩数据后使用客户端的解压缩进行调试。客户端中为解压缩功能传递的相同参数在服务器端使用Z_DATA_ERROR失败。数据的MD5sum似乎相同。我完全无能为力,接下来我能做什么。
Server Side cod看起来像这样:
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-&gt; 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;
}
答案 0 :(得分: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()函数,(ZSWAP32(hold))!= state-&gt; check)”中失败了。所以我无法相信函数uncompress与数据模式有关。我错了吗?
我还注意到压缩函数调用deflate进行压缩,每隔64k对进程数据进行一次收缩,所以需要将其拆分为64k块,逐个压缩每个块,然后解压缩才能正常工作?
答案 1 :(得分:-1)
我不知道这是否是正确的答案,也许它有帮助!我的英语太差了,希望你能理解。也许转换为另一个的参数有bug。当他们转换信息可能会输!我遇到同样的问题,使用源代码类型后问题已解决(Bytef \ uLongf \ uLong等)。结婚是中国人,你可以使用谷歌翻译。 http://www.360doc.com/content/13/0927/18/11217914_317498849.shtml
答案 2 :(得分:-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;
}