我正在侦听来自多播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。
答案 0 :(得分:1)
使用deflate()
调用Z_FINISH
表示您已经或者已经提供了deflate
最后一个输入数据。然后deflate
将终止该流。一旦提供了足够的输出空间来写入最后一个压缩数据,这可能是第一次这样的调用,deflate()
将返回Z_STREAM_END
,而不是Z_OK
。然后,deflate()
引擎已完成,除非您执行deflateEnd()
后跟deflateInit()
,或等效且更快,deflateReset()
,否则无法再次使用。
看来,您所缺少的是阅读文档后获得的奖励。