我有一个应用程序,它有一个c++服务器和一个c#客户端。我使用TZlibTransport.cpp在服务器上进行zlib压缩,并使用一个包装器使用Ionic.Zlib解压缩客户机中的数据,这在大多数情况下都是有效的。
我注意到,在非常特殊的情况下,客户端会遇到以下错误之一:
Thrift.Protocol.TProtocolException: Missing version in readMessageBegin, old client?
at Thrift.Protocol.TBinaryProtocol.ReadMessageBegin()
Ionic.Zlib.ZlibException: Bad state (invalid block type)
at Ionic.Zlib.InflateManager.Inflate(FlushType flush)我发现在发生这些错误的所有情况下,服务器发送了两个包,一个刚刚超过1024字节(这是TZlibTransport.cpp使用的TZlibTransport.cpp的大小),另一个是5-8字节。查看第二个包上的数据,我注意到zlib使用的是刷新标记,添加了两次,
ff ff 00 00 00 ff ff将第一个标记的第一部分放在前一个包的末尾。如果我稍微增加缓冲区的大小,以便它有足够的空间在一个包中写入标记,那么就不会发生崩溃,所以--我相信是这个标记被添加了两次--导致了问题。但是,仅仅更改缓冲区大小并不是一种解决方案,因为这意味着错误发生在应用程序中的其他地方。
我研究了zlib,发现如果缓冲区(https://github.com/madler/zlib/issues/149)中没有足够的空间,这就是预期的行为。然而,我还没有找到任何遇到这种情况的人,这给节俭带来了问题。
因此,我的问题是,对于特定的数据长度,节俭是否会将标记拆分成多个包,以及客户机应该如何处理这个问题。
发布于 2018-08-10 22:17:58
看起来问题不在于标记发出了两次,而是因为第一个标记并不完全适合缓冲区。如果输出只是ff ff,那么您就会遇到完全相同的问题和相同的错误消息。ff无法启动泄气流,因为它提供了无效的块类型(3)。
从您的描述中,听起来似乎存在一个漏洞,因为它不能保证和/或检查所有压缩数据是否确实适合缓冲区。
https://stackoverflow.com/questions/51784225
复制相似问题