我正在使用Qt在NMDC客户端(p2p,DC ++和朋友)上工作。协议本身非常简单:
$command parameters|
compression除外:
“ZPipe通过向客户端发送命令$ ZOn来工作。在$ ZOn之后,包含命令的ZLib压缩流将跟随。此流将以ZLib定义的EOF结束。(压缩流中没有$ ZOff) !)“
以下是相关代码:
QTcpSocket *conn;
bool compressed;
QByteArray zbuffer;
QByteArray buffer;
// ...
void NMDCConnection::on_conn_readyRead() {
// this gets called whenever we get new data from the hub
if(compressed) { // gets set when we receive $ZOn
zbuffer.append(conn->readAll());
// Magic happens here
if( stream_is_complete ) {
buffer.append(uncompressed_stream);
buffer.append(remainder_of_data);
compressed = false;
}
} else {
buffer.append(conn->readAll());
};
parse(buffer);
}
那么,如何获取stream_is_complete
,uncompressed_stream
和remainder_of_data
的值?我不能寻找下一个'$'因为流可以包含它。我尝试在zlib文档中寻找类似于EOF的东西,但是没有这样的东西,事实上,每个流都以看似随机的字符结尾。
我也玩过qUncompress(),但是这需要一个完整的流,没有更多,仅此而已。
答案 0 :(得分:1)
您是否直接使用zlib?
完全未经测试......
z_stream zstrm;
QByteArray zout;
// when you see a $ZOn|, initialize the z_stream struct
parse() {
...
if (I see a $ZOn|) {
zstrm.next_in = Z_NULL;
zstrm.avail_in = 0;
zstrm.zalloc = Z_NULL;
zstrm.zfree = Z_NULL;
zstrm.opaque = 0;
inflateInit(&zstrm);
compressed = true;
}
}
void NMDCConnection::on_conn_readyRead() {
if (compressed) {
zbuffer.append(conn->readAll());
int rc;
do {
zstrm.next_in = zbuffer.data();
zstrm.avail_in = zbuffer.size();
zout.resize(zstrm.total_out + BLOCK_SIZE);
zstrm.next_out = zout.data() + zstrm.total_out;
zstrm.avail_out = BLOCK_SIZE;
rc = inflate(&zstrm, Z_SYNC_FLUSH);
zbuffer.remove(0, zstrm.next_in - zbuffer.data());
} while (rc == Z_OK && zstrm->avail_out == 0);
if (rc == Z_STREAM_END) {
zout.truncate(zstrm.total_out);
buffer.append(zout);
zout.clear();
buffer.append(zbuffer);
zbuffer.clear();
compress = false;
inflateEnd(&zstrm);
}
else if (rc != Z_OK) {
// ERROR! look at zstrm.msg
}
}
else // whatever
}
这会逐渐从qbuffer
解压缩(膨胀)到qout
,并在inflate
说“不再”时停止。
也许最好从QuaZip借用。
答案 1 :(得分:0)
文件结尾对zlib并不特殊。我在您的代码中看到的问题是您使用“readAll()”,它实际上没有任何报告“错误”的方法,例如文件结束。
你应该尝试在循环中使用“read()”。如果您读取流并返回0字节读取,则可以确定已到达流的末尾(另一端已关闭连接)。你读过的缓冲区加入了循环中所有先前“读取”的缓冲区,将为你提供完整的缓冲区。