Я пишу клиентское приложение на основе 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