Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 如何从zlib确定压缩数据的压缩大小?_Sockets_Gzip_Zlib - Fatal编程技术网

Sockets 如何从zlib确定压缩数据的压缩大小?

Sockets 如何从zlib确定压缩数据的压缩大小?,sockets,gzip,zlib,Sockets,Gzip,Zlib,我正在使用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

我正在使用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流。”写入缓冲区是可行的(然后我可以随后将缓冲区写入套接字),但我看不出如何使用接口来实现这一点。

您可以通过
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);
}
#包括
#包括
#包括
字符输入缓冲区[4096];
字符输出缓冲区[4096];
int main(int argc,char*argv[])
{
z_溪;
int输入大小;
文件*FileP;
Stream.zalloc=malloc;
Stream.zfree=自由;
/*初始化压缩*/
排气装置(和气流,3);
FileP=fopen(“test.c”、“rb”);
InputSize=fread((void*)InputBufferA,1,sizeof(InputBufferA),FileP;
fclose(FileP);
Stream.next_in=InputBufferA;
Stream.avail_in=输入大小;
Stream.next_out=OutputBufferA;
Stream.avail_out=sizeof(OutputBufferA);
放气(&Stream,Z_SYNC_FLUSH);
/*OutputBufferA现在由压缩数据填充*/
printf(“%d字节输入压缩为%d字节\n”,Stream.total\u输入,Stream.total\u输出);
出口(0);
}

请参阅
zlib.h
中的
deflate
文档,zlib实际上可以将gzip格式的数据写入内存中的缓冲区

此条目遵从zlib.h中的注释。在头文件中,deflateInit2()的注释提到应该(任意地)在第四个参数(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. */
#包括
z_溪;
stream.zalloc=Z_NULL;
stream.zfree=Z_NULL;
stream.opaque=Z_NULL;
int level=Z_默认值_压缩;
int method=Z_DEFLATED;/*强制性的*/
int windowBits=15+16;/*15是默认值,就像deflateInit一样*/
/*使用时,添加16以启用gzip格式*/
int memLevel=8;/*违约*/
int strategy=Z_DEFAULT_策略;
if(deflateInit2(&stream,level,method,windowBits,memLevel,strategy)!=Z_OK)
{
fprintf(stderr,“deflateInit失败\n”);
退出(退出失败);
}
/*现在像往常一样使用deflate函数来压缩gzip*/
/*从一个缓冲区到另一个缓冲区*/

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

不确定是否遗漏了某些内容,但这似乎不会生成gzip格式的数据。