распаковка zlib () странным образом возвращает Z_BUF_ERROR - PullRequest
1 голос
/ 30 июня 2011

Я пишу клиентское приложение на основе Qt.Он подключается к удаленному серверу, используя QTcpSocket.Перед отправкой каких-либо фактических данных необходимо отправить информацию для входа в систему, которая является zlib-сжатой json.

Насколько я знаю из серверных источников, чтобы все работало, мне нужно отправить X байтов сжатых данных, следующие 4 байта.с длиной несжатых данных.

Распаковка на стороне сервера выглядит следующим образом:

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

Я сжимаю json, используя встроенный в Qt zlib (я только что скачал заголовки и поместилэто в папке include mingw):

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;
}

Полный код функции здесь: http://pastebin.com/hMY2C4n5

Даже если сервер правильно получает несжатую длину, uncompress() возвращает Z_BUF_ERROR.

PS: На самом деле я пишу клиент pushpool, чтобы понять, как работает его двоичный протокол.Я задавал этот вопрос на официальном форуме биткойнов, но не повезло.http://forum.bitcoin.org/index.php?topic=24257.0

1 Ответ

1 голос
/ 07 июня 2012

Оказывается, это была ошибка на стороне сервера.Больше подробностей в ветке форума биткойнов.

...