IOS应用程序与Nitty通信(解压缩)

时间:2013-12-02 23:21:29

标签: java objective-c gzip netty compression

请帮我弄清楚解压缩从Nitty 4.0服务器收到的数据的方法。 由于服务器端的deflate功能使用JDK1.7 gzip,包括Huffman算法和LZ77。

所以当服务器第一次发送压缩的数据时,我使用Gzip库:

- (NSData *) gzipInflate

{     z_stream strm;

// Initialize input
strm.next_in = (Bytef *)[self bytes];
NSUInteger left = [self length];        // input left to decompress
if (left == 0)
    return nil;                         // incomplete gzip stream

// Create starting space for output (guess double the input size, will grow
// if needed -- in an extreme case, could end up needing more than 1000
// times the input size)
NSUInteger space = left << 1;
if (space < left)
    space = NSUIntegerMax;
NSMutableData *decompressed = [NSMutableData dataWithLength: space];
space = [decompressed length];

// Initialize output
strm.next_out = (Bytef *)[decompressed mutableBytes];
NSUInteger have = 0;                    // output generated so far

// Set up for gzip decoding
strm.avail_in = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
int status = inflateInit2(&strm, (15+16));
if (status != Z_OK)
    return nil;                         // out of memory

// Decompress all of self
do {
    // Allow for concatenated gzip streams (per RFC 1952)
    if (status == Z_STREAM_END)
        (void)inflateReset(&strm);

    // Provide input for inflate
    if (strm.avail_in == 0) {
        strm.avail_in = left > UINT_MAX ? UINT_MAX : (unsigned)left;
        left -= strm.avail_in;
    }

    // Decompress the available input
    do {
        // Allocate more output space if none left
        if (space == have) {
            // Double space, handle overflow
            space <<= 1;
            if (space < have) {
                space = NSUIntegerMax;
                if (space == have) {
                    // space was already maxed out!
                    (void)inflateEnd(&strm);
                    return nil;         // output exceeds integer size
                }
            }

            // Increase space
            [decompressed setLength: space];
            space = [decompressed length];

            // Update output pointer (might have moved)
            strm.next_out = (Bytef *)[decompressed mutableBytes] + have;
        }

        // Provide output space for inflate
        strm.avail_out = space - have > UINT_MAX ? UINT_MAX :
        (unsigned)(space - have);
        have += strm.avail_out;

        // Inflate and update the decompressed size
        status = inflate (&strm, Z_SYNC_FLUSH);
        have -= strm.avail_out;

        // Bail out if any errors
        if (status != Z_OK && status != Z_BUF_ERROR &&
            status != Z_STREAM_END) {
            (void)inflateEnd(&strm);
            return nil;                 // invalid gzip stream
        }

        // Repeat until all output is generated from provided input (note
        // that even if strm.avail_in is zero, there may still be pending
        // output -- we're not done until the output buffer isn't filled)
    } while (strm.avail_out == 0);

    // Continue until all input consumed
} while (left || strm.avail_in);

// Free the memory allocated by inflateInit2()
(void)inflateEnd(&strm);

// Verify that the input is a valid gzip stream
// if (status != Z_STREAM_END)
// return nil;                         // incomplete gzip stream

// Set the actual length and return the decompressed data
[decompressed setLength: have];
return decompressed;

}

因此,如果您熟悉DEFLATE的霍夫曼算法(我希望) 下一次nitty放气相同的字符串发送它我收到它但比第一次短,我不能给它充气,

有没有办法将inflate应用为Huffman Tree算法,将LZ77应用为Java Nitty Server?

1 个答案:

答案 0 :(得分:0)

现在您已在下面的评论中提供了数据,很明显发生了什么。第二个字符串是第一个字符串的延续。您只需将后续数据保存到同一个膨胀实例中即可。

第一个字符串启动gzip流并以空块结束,但不终止该流。第二个字符串继续使用更多的膨胀块,这些块指的是第一个字符串。

第二个字符串也不是结尾。之后应该有更多,因为它也不会终止gzip流。最终你应该得到一个完成gzip流的数据包,在这种情况下inflate()将返回Z_STREAM_END