C++ zlib';s uncompress()奇怪地返回Z_BUF_错误

C++ zlib';s uncompress()奇怪地返回Z_BUF_错误,c++,qt,zlib,bitcoin,C++,Qt,Zlib,Bitcoin,我正在编写基于Qt的客户端应用程序。它使用QTcpSocket连接到远程服务器。在发送任何实际数据之前,它需要发送登录信息,即zlib压缩json 据我从服务器源代码所知,为了使一切正常工作,我需要在4字节的未压缩数据长度之后发送X字节的压缩数据 在服务器端解压缩如下所示: /* look at first 32 bits of buffer, which contains uncompressed len */ unc_len = le32toh(*((uint32_t *)buf)); if

我正在编写基于Qt的客户端应用程序。它使用
QTcpSocket
连接到远程服务器。在发送任何实际数据之前,它需要发送登录信息,即zlib压缩json

据我从服务器源代码所知,为了使一切正常工作,我需要在4字节的未压缩数据长度之后发送X字节的压缩数据

在服务器端解压缩如下所示:

/* look at first 32 bits of buffer, which contains uncompressed len */
unc_len = le32toh(*((uint32_t *)buf));
if (unc_len > CLI_MAX_MSG)
    return NULL;

/* alloc buffer for uncompressed data */
obj_unc = malloc(unc_len + 1);
if (!obj_unc)
    return NULL;

/* decompress buffer (excluding first 32 bits) */
comp_p = buf + 4;
if (uncompress(obj_unc, &dest_len, comp_p, buflen - 4) != Z_OK)
    goto out;
if (dest_len != unc_len)
    goto out;
memcpy(obj_unc + unc_len, &zero, 1);    /* null terminate */
我正在使用Qt内置的zlib压缩json(我刚刚下载了标题并将其放在mingw的
include
文件夹中):

char-json[]=“{\'版本\':1,\'用户\':\'测试\'”;
字符通过[]=“测试”;
std::auto_ptr消息(新的Bytef[//分配内存用于:
sizeof(ubbp_头)//+msg头
+sizeof(uLongf)/+未压缩数据大小
+strlen(json)/+压缩数据本身
+64//+保留(如果压缩大小>未压缩大小)
+SHA256_摘要_长度];/+SHA256文摘
uLongf unc_len=strlen(json);
uLongf enc_len=strlen(json)+64;
//头先到达,所以服务器将确定我们要登录
Bytef*pHdr=message.get();
//之后:未压缩的数据长度和数据本身
Bytef*pLen=pHdr+sizeof(ubbp_头);
Bytef*pDat=pLen+sizeof(uLongf);
//使用用户密码更新的压缩消息哈希
Bytef*pSha;
if(Z_OK!=压缩(pLen和enc_len,(Bytef*)json,unc_len))
{
qDebug(“压缩失败”);
返回false;
}
在此填写完整的功能代码:

即使服务器正确地接收到未压缩的长度,
uncompress()
返回
Z_BUF_错误


注:我正在编写pushpool的客户端,以了解它的二进制协议是如何工作的。我在比特币官方论坛上问过这个问题,但在那里运气不好

原来是服务器端的bug。比特币论坛线程中有更多详细信息。

证明这是服务器端错误。更多详情请参见比特币论坛帖子

char json[] = "{\"version\":1,\"user\":\"test\"}";
char pass[] = "test";

std::auto_ptr<Bytef> message(new Bytef[             // allocate memory for:
                             sizeof(ubbp_header)    //  + msg header
                             + sizeof(uLongf)       //  + uncompressed data size
                             + strlen(json)         //  + compressed data itself
                             + 64                   //  + reserve (if compressed size > uncompressed size)
                             + SHA256_DIGEST_LENGTH]);//+ SHA256 digest

uLongf unc_len = strlen(json);
uLongf enc_len = strlen(json) + 64;

// header goes first, so server will determine that we want to login
Bytef* pHdr = message.get();

// after that: uncompressed data length and data itself
Bytef* pLen = pHdr + sizeof(ubbp_header);
Bytef* pDat = pLen + sizeof(uLongf);

// hash of compressed message updated with user pass
Bytef* pSha;

if (Z_OK != compress(pLen, &enc_len, (Bytef*)json, unc_len))
{
    qDebug("Compression failed.");
    return false;
}