4

我正在使用 zlib 执行 gzip 压缩。zlib 将数据压缩后直接写入打开的 TCP 套接字。

/* socket_fd is a file descriptor for an open TCP socket */
gzFile gzf = gzdopen(socket_fd, "wb");
int uncompressed_bytes_consumed = gzwrite(gzf, buffer, 1024);

(当然所有错误处理都被删除了)

问题是:如何确定向套接字写入了多少字节?zlib 中的所有 gz* 函数都处理未压缩域中的字节数/偏移量,并且 tell (seek) 不适用于套接字。

zlib.h 标头说“这个库也可以选择在内存中读取和写入 gzip 流。” 写入缓冲区会起作用(然后我可以随后将缓冲区写入套接字),但我看不到如何使用接口执行此操作。

4

2 回答 2

0

您将能够通过deflate*一系列调用来做到这一点。我不会向您展示所有内容,但是这个示例程序(我在目录中将其命名为“test.c”)应该可以帮助您入门:

#include <zlib.h>
#include <stdlib.h>
#include <stdio.h>

char InputBufferA[4096];
char OutputBufferA[4096];

int main(int argc, char *argv[])
{
    z_stream Stream;
    int InputSize;
    FILE *FileP;

    Stream.zalloc = malloc;
    Stream.zfree = free;
    /* initialize compression */
    deflateInit(&Stream, 3);
    FileP = fopen("test.c", "rb");
    InputSize = fread((void *) InputBufferA, 1, sizeof(InputBufferA), FileP);
    fclose(FileP);
    Stream.next_in = InputBufferA;
    Stream.avail_in = InputSize;
    Stream.next_out = OutputBufferA;
    Stream.avail_out = sizeof(OutputBufferA);
    deflate(&Stream, Z_SYNC_FLUSH);
    /* OutputBufferA is now filled in with the compressed data. */
    printf("%d bytes input compressed to %d bytes\n", Stream.total_in, Stream.total_out);
    exit(0);
}

从查阅deflate文档zlib.h

于 2010-01-20T18:30:29.547 回答
0

实际上,zlib 可以将 gzip 格式的数据写入内存中的缓冲区。

zlib 常见问题解答条目遵循 zlib.h 中的注释。在头文件中,deflateInit2() 的注释提到您应该(任意?)将 16 添加到第 4 个参数(windowBits),以使库使用 gzip 格式(而不是默认的“zlib “ 格式)。

此代码正确设置 zlib 状态以将 gzip 编码到缓冲区:

#include <zlib.h>
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
int level = Z_DEFAULT_COMPRESSION;
int method = Z_DEFLATED;  /* mandatory */
int windowBits = 15 + 16; /* 15 is default as if deflateInit */
                          /* were used, add 16 to enable gzip format */
int memLevel = 8;         /* default */
int strategy = Z_DEFAULT_STRATEGY;
if(deflateInit2(&stream, level, method, windowBits, memLevel, strategy) != Z_OK)
{
    fprintf(stderr, "deflateInit failed\n");
    exit(EXIT_FAILURE);
}

/* now use the deflate function as usual to gzip compress */
/* from one buffer to another. */

我确认此过程产生与 gzopen/gzwrite/gzclose 接口完全相同的二进制输出。

于 2010-01-22T23:08:32.030 回答