gpt4 book ai didi

使用 zlib 库压缩多播数据包

转载 作者:行者123 更新时间:2023-11-30 15:22:58 26 4
gpt4 key购买 nike

我正在监听来自多播 IP 端口的数据包,并尝试使用 zlib 库压缩该数据包(想知道实时数据包中 zlib 的压缩率,因为这是我们客户的要求)。我已经实现了 zlib 压缩代码,如下所示,但是 outputDataBuffer 的长度打印不正确,我不知道我错过了什么。

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <zlib.h>

using namespace std;
struct sockaddr_in localSock;
struct ip_mreq group;
int maxpacketsize = 1500;

void connectSocket(int &sd,char *multicastIP,int multicastPort,char *interfaceIP);
void listenSocket(int &sd,const short &structureSize,const short &compressionType);
void compressZlib(char *inputDataBuffer,int inputDataLength,z_stream &defstream)

int main(int argc, char *argv[])
{
int sd = 0;
char multicastIP[16]="230.0.0.50";
char interfaceIP[16]="192.168.225.132";
int multicastPort = 13551;
short structureSize = 0;
connectSocket(sd,multicastIP,multicastPort,interfaceIP);
listenSocket(sd,structureSize);
return 0;
}

void connectSocket(int &sd,char *multicastIP,int multicastPort,char *interfaceIP)
{
int reuse = 1;
sd = socket(AF_INET, SOCK_DGRAM, 0);
if(sd < 0)
{
perror("Opening datagram socket error");
exit(1);
}
printf("Opening datagram socket....OK.\n");
if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
{
perror("Setting SO_REUSEADDR error");
close(sd);
exit(1);
}
printf("Setting SO_REUSEADDR...OK.\n");

memset((char *) &localSock, 0, sizeof(localSock));
localSock.sin_family = AF_INET;
localSock.sin_port = htons(multicastPort);
localSock.sin_addr.s_addr = INADDR_ANY;
if(bind(sd, (struct sockaddr*)&localSock, sizeof(localSock)))
{
perror("Binding datagram socket error");
close(sd);
exit(1);
}
printf("Binding datagram socket...OK.\n");
group.imr_multiaddr.s_addr = inet_addr(multicastIP);
group.imr_interface.s_addr = inet_addr(interfaceIP);
if(setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0)
{
perror("Adding multicast group error");
close(sd);
exit(1);
}
printf("Adding multicast group...OK.\n");
}

void compressZlib(char *inputDataBuffer,int inputDataLength,z_stream &defstream)
{

char *outputDataBuffer = new char[inputDataLength];
memset(outputDataBuffer,0,inputDataLength);
defstream.avail_in = (uInt)strlen(inputDataBuffer)+1;
defstream.next_in = (Bytef *)inputDataBuffer;
defstream.avail_out = (uInt)sizeof(outputDataBuffer);
defstream.next_out = (Bytef *)outputDataBuffer;

if(deflate(&defstream, Z_FINISH) != Z_OK )
{
cout<<"Error"<<endl;
}
//printf("%lu %lu\n", inputDataLength,defstream.total_in);
printf("%lu %lu\n", inputDataLength,strlen(outputDataBuffer));
}

void listenSocket(int &sd,const short &structureSize)
{
char databuf[5000] = "";
int receivedBytes = 0;
z_stream defstream;
defstream.zalloc = Z_NULL ;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
deflateInit(&defstream, Z_FULL_FLUSH);
while(1)
{
int socklen = sizeof(struct sockaddr_in);
struct sockaddr_in saddr;
receivedBytes = recvfrom(sd, databuf, maxpacketsize, 0, (struct sockaddr *)&saddr, (socklen_t*)&socklen);
if(receivedBytes < 0)
{
perror("Reading datagram message error");
close(sd);
exit(1);
}
compressZlib(databuf,receivedBytes,defstream);
//compressZlib(databuf1,strlen(databuf1));
//compressZlib();
//cout<<receivedBytes<<endl;

}
deflateEnd(&defstream);
}

我还使用了 compress2() 函数,如下所示:

compress2((unsigned char*)outputBuffer,&outputDataLength,(const unsigned char*)inputBuffer,(unsigned long)inputBufferLength,Z_DEFAULT_COMPRESSION);

但这也不起作用,outputDataLength 始终为 0。

最佳答案

使用 Z_FINISH 调用 deflate() 意味着您正在或已经输入了 deflate 最后的输入数据。然后 deflate 将终止流。一旦提供了足够的输出空间来写入最后的压缩数据(很可能是在第一次此类调用时),deflate() 将返回 Z_STREAM_END,而不是Z_OK。然后 deflate() 引擎就完成了,并且不能再次使用,除非您执行 deflateEnd() 后跟 deflateInit(),或者等效且更快的 deflateReset()

看来您缺少的是阅读文档所带来的奖励。

关于使用 zlib 库压缩多播数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28963857/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com