我正在使用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流。”写入缓冲区会起作用(然后我可以随后将缓冲区写入套接字),但我看不到如何使用该接口。
答案 0 :(得分: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
文档。
答案 1 :(得分:0)
此zlib faq条目遵循zlib.h中的注释。在头文件中,deflateInit2()的注释提到您应该(任意?)将第16个参数(windowBits)添加16,以便使库使用gzip格式(而不是默认的“zlib”)格式化deflate流“格式化。”
此代码正确设置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接口完全相同的二进制输出。