【问题标题】:zlib compression and decompressionzlib 压缩和解压
【发布时间】:2016-12-30 15:48:28
【问题描述】:

我正在尝试通过套接字发送一些 zlib 压缩数据,然后在从套接字接收后将其膨胀到另一个代码中。我能够成功解压缩第一个数据包,但是后续数据包没有被解压缩,inflate 函数返回 -2 错误代码。以下是sn-ps的代码:

服务器.cpp

` //Main里面

 { 

 z_stream defstream;
memset(&defstream, 0, sizeof(defstream));
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;

err = deflateInit(&defstream, Z_BEST_COMPRESSION);
if(err == Z_OK)
     {
            //do nothing
     }
    else
    {
            deflateEnd(&defstream);
            exit(1);
    }


    std::string outstring;
    int ret = 0;

    char a[6] = "Hello" ;
while(1)
    {

printf("Uncompressed size is: %lu\n", strlen(a));


printf("\n----------\n\n");

    SendCompressString(a);
    memset(a,'\0',6);
    strncpy(a,"Hello",5);
    }

    return 0;}
  int SendCompressString(char *a)

  {

    char xyx[100];


    char abc[100];


    int iLen = 0;
    int iRetval = 0;


char b[100];


char c[100];



z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
// setup "a" as the input and "b" as the compressed output
defstream.avail_in = (uInt)strlen(a)+1; // size of input, string + terminator
defstream.next_in = (Bytef *)a; // input char array
defstream.avail_out = (uInt)sizeof(b); // size of output
defstream.next_out = (Bytef *)b; // output char array

// the actual compression work.
deflateInit(&defstream, Z_BEST_COMPRESSION);
deflate(&defstream, Z_FINISH);
deflateEnd(&defstream);


printf("Compressed size is: %lu\n", strlen(b));
printf("Compressed string is: %s\n", b);

strncpy(xyx,"M1234",5);
sprintf(abc,"%04d",defstream.total_out);
strcat(xyx,abc);
memcpy(xyx + 9,b,defstream.total_out);
printf("Compressed string is: [%s\n]", xyx);

printf("\n----------\n\n");
            iLen = defstream.total_out + 9;
            if ((iRetval = Send(connected, (CHAR *)xyx,&iLen , 0)) == FALSE)
            {
                    logError("ERROR IN SENDING THE DATA TO SOCKET");
                    logDebug3("Send Failed For IP Addr") ;
             } return 0;}

客户端.cpp

     z_stream infstream;
     int err = 0;


    infstream.next_in = Z_NULL;
    infstream.avail_in = 0;
    infstream.zalloc = Z_NULL;
    infstream.zfree = Z_NULL;
    infstream.opaque = Z_NULL;
    err = inflateInit (&infstream);
    if(err == Z_OK)
     {
            //do nothing
     }
    else
    {
            inflateEnd(&infstream);
            exit(1);
    }


    struct timeval stop, start,start1;

    while(1)
    {
            PcktCount++;
            LogTaBLib.debug("%s|%s|%d|================== Waiting on socket %d ==============",basename(__FILE__),__func__,__LINE__, iMasterSoc);
            memset(AppMsg, '\0', MAX_PACKET_SIZE);
            pHeader = NULL;
            Datas = NULL;

            iLen1 = 9;

            if ((iRetval = Recv(iMasterSoc,(CHAR *) AppMsg,&iLen1,MSG_PEEK)) == FALSE)
            {
                    LogTaBLib.debug("%s|%s|%d|Dropped Exchange Response Receiving from Socket",basename(__FILE__),__func__,__LINE__);
                    LogTaBLib.info("%s|%s|%d| CONNECTION DOWN ",basename(__FILE__),__func__,__LINE__);
                    //break;
                    exit(1);
            }

            pHeader = (struct BCAST_HEADER_DATA *)AppMsg;



            //TWIDDLE1(pHeader->dSeqNum);
            //TWIDDLE1(pHeader->dMsgLen);


            iLen1 = atoi((const char*)(AppMsg + 5)) + 9;

            if (iLen1 < 1024)
            {

            memset(AppMsg, '\0', MAX_PACKET_SIZE);

            if ((iRetval = Recv(iMasterSoc, (CHAR *)AppMsg,&iLen1,0)) == FALSE)
            {
                    perror("The Error Is :");
                    LogTaBLib.debug("%s|%s|%d|Dropped Exchange Response Receiving from Socket",basename(__FILE__),__func__,__LINE__);
                    LogTaBLib.info("%s|%s|%d| CONNECTION DOWN ",basename(__FILE__),__func__,__LINE__);
                    //break;
                    exit(1);
            }
            }
            else
            {
                    CHAR *Ptr = NULL;
                    Ptr = (CHAR *) malloc (iLen1);
                    memset(Ptr,'\0',iLen1);
                    if ((iRetval = Recv(iMasterSoc, (CHAR *)Ptr,&iLen1,0)) == FALSE)
                    {
                    perror("The Error Is :");
                    LogTaBLib.debug("%s|%s|%d|Dropped Exchange Response Receiving from Socket",basename(__FILE__),__func__,__LINE__);
                    LogTaBLib.info("%s|%s|%d| CONNECTION DOWN ",basename(__FILE__),__func__,__LINE__);
                    exit(1);
                    }
                    free(Ptr);
                    Ptr = NULL;
                    continue;
            }


            pHeader = NULL;
            pHeader = (struct BCAST_HEADER_DATA *)AppMsg;


            //TWIDDLE1(pHeader->dSeqNum);
            //TWIDDLE1(pHeader->dMsgLen);


            iLen1 = iLen1 - 9;
            if(CompressionFlag == TRUE)
            {
                    memset(Uncompressed,'\0',MAX_PACKET_SIZE);
                    memset(CompData,'\0',MAX_PACKET_SIZE);
                    memcpy(CompData,AppMsg+9,iLen1);
                    LogTaBLib.info("%s|%s|%d| CompData Is [%s] iLen1 [%d]",basename(__FILE__),__func__,__LINE__,CompData,iLen1);

                    gettimeofday(&start, NULL);
                    infstream.avail_in = iLen1 ;
                    infstream.next_in = (Bytef *)CompData; // input char array
                    infstream.avail_out = (uInt)sizeof(Uncompressed); // size of output
                    infstream.next_out = (Bytef *)Uncompressed; // output char array

                            err = inflate(&infstream, Z_NO_FLUSH);
                            if(err == Z_OK)
                            {
                                    //      do nothing
                            }
                            else
                               {
                                    LogTaBLib.info("%s|%s|%d|Failed With [%d] ",basename(__FILE__),__func__,__LINE__,err);
                                    inflateEnd(&infstream);
                               }

                    gettimeofday(&stop, NULL);
                    LogTaBLib.info("%s|%s|%d|Uncompressed[%s] Length[%d]",basename(__FILE__),__func__,__LINE__,Uncompressed,iLen1);

            }
            iLen1 =0;

            memset(buffer,'\0',200);

`

这是发送的第一个字符串的输出:

INFO|2016-12-30|21:33:37,875443||||||TestZlib.cpp|main|481|未压缩[Hello] 长度[14]| 解码消息的秒数是:[54]

对于第二个和后续字符串,我得到与输入相同的字符串,但我无法解压缩:

INFO|2016-12-30|21:33:37,875739||||||TestZlib.cpp|main|481|Uncompressed[] 长度[14]|

【问题讨论】:

    标签: c zlib compression


    【解决方案1】:

    -2 是Z_STREAM_ERROR,这表明您在执行inflateInit()inflate() 之间的某个时间以某种方式破坏了zlib 流数据结构。你应该检查你所有的memset()s 和memcpy()s 以确保它们保持在它们应该写入的内存范围内。

    您还应该阅读documentation for zlib in zlib.h,以及查看example of how,应该使用inflate()deflate() 函数。例如,完全膨胀的成功不是由Z_OK 表示,而是由Z_STREAM_END 表示。此外,您没有检查 deflate* 函数上的错误代码。

    最后,您应该在一个程序中测试并验证您对deflate()inflate() 的使用,中间不要使用套接字,以确保在开始复杂化之前您已经掌握了这一点。

    【讨论】:

    • 感谢 Mark...当我在同一代码中进行通货膨胀和通货紧缩时,它的工作原理。只有当我将它通过套接字时,它才停止工作。
    • 我做了一些更改,现在放气函数返回 0 (Z_OK)。但是这次 inflate 返回我 -3 (DATA_ERROR)。
    • 假设代码在没有套接字的情况下工作,那么您没有忠实地通过套接字传输数据。逐字节比较你输入套接字的内容和另一端输出的内容,看看问题出在哪里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多