免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 15565 | 回复: 9
打印 上一主题 下一主题

[C] C语言抓http gzip包并解压 失败 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-10 15:06 |只看该作者 |倒序浏览
写一个C语言程序,抓取http的包,在本程序中,要求抓取gzip格式的包,并且进行解压。
代码如下
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <zlib.h>

#define BUFSIZE 10240
#define DestIp "58.61.166.67"
#define DestPort 80
#define Req "GET /cgi-bin/qqshow_user_searchitem?search_str=搞怪&style=1&nowpage=1&sorttype=0&content=&sex=0 HTTP/1.1\r\nAccept: */*\r\nAccept-Language: zh-cn\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\r\nHost: 58.61.166.67\r\nConnection: Keep-Alive\r\nCookie: pvid=1250811316; edition=4m16.mail.qq.com; CCSHOW=0000; ruv=3715021559298\r\n\r\n"
#define ReqLen sizeof(Req)

int main(int argc, char *argv[])
{
    ssize_t i;
    int nRequestLen;
    int templen = 0;
    int c;

    gzFile file, zip;
    Byte compr[BUFSIZE], uncompr[BUFSIZE];
    uLong comprLen, uncomprLen;

    char strResponse[BUFSIZE]={0};
    char strRequest[BUFSIZE]={0};
    char strGzip[BUFSIZE]={0};
    char *pA = NULL;


    int sockfd, numbytes;
    struct sockaddr_in dest_addr; /* connector's address information */

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    dest_addr.sin_family = AF_INET; /* host byte order */
    dest_addr.sin_port = htons(DestPort); /* short, network byte order */
    dest_addr.sin_addr.s_addr = inet_addr(DestIp);

    /* Create and setup the connection */
    if (connect(sockfd, (struct sockaddr *)&dest_addr,sizeof(struct sockaddr)) == -1) {
        perror("connect");
        exit(1);
          }

    /* Send the request */
    strncpy(strRequest, Req,ReqLen);
    nRequestLen = ReqLen;
    if (write(sockfd,strRequest,nRequestLen) == -1) {
    perror("write");
    exit(1);
    }
    /* Read in the response */
    while(1) {
        i = read(sockfd,strResponse + templen,BUFSIZE-1);
        if(0 >= i){
            break;
        }
        //strResponse='\0';
        templen = templen + i;
    }
        printf(strResponse);
        pA = strstr(strResponse, "\r\n\r\n");

        printf("%d\n", templen);
        printf("%d\n", pA - strResponse);
        printf(pA);

        memcpy(strGzip, pA + 4, templen - ((pA - strResponse) + 4));
        printf("\nooooooo\n");

        //gzprintf(file, strGzip);

        //comprLen = sizeof(file) / sizeof(compr[0]);
        comprLen = (templen - ((pA - strResponse) +4));
        printf("%d\n", comprLen);

        //strcpy((char *)uncompr, "garbage");
        int err = uncompress(uncompr, &uncomprLen, (const Bytef*)strGzip, comprLen);
        if (err != Z_OK){
            printf("uncompress error:%d\n", err);
            exit(1);
        }
       
    /* Close the connection */
    close(sockfd);
}

按理论来说,成功的话应该返回解压内容的,可是结果却是:
HTTP/1.1 200 OK
Date: Tue, 10 Jul 2007 07:05:46 GMT
Server: Apache
Expires: 0
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 61
Connection: close
Content-Type: text/html; charset=gb2312

272
207



ooooooo
61
uncompress error:-3

请问有人写过类似的程序吗?

[ 本帖最后由 tedli 于 2007-7-10 15:12 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-07-10 17:29 |只看该作者
我的也不对
不知道什么原因
郁闷啊

论坛徽章:
0
3 [报告]
发表于 2007-07-10 19:57 |只看该作者
gzip文件不是文本格式,而你用字符串函数strstr等进行处理,这肯定是不行的.

论坛徽章:
0
4 [报告]
发表于 2007-07-11 08:27 |只看该作者
Content-Length: 61
指定了返回内容的长度, \r\n\r\n 后面是返回内容, 应该就是你的gzip文件
你的程序都没 http 解析,怎么用?

论坛徽章:
0
5 [报告]
发表于 2007-07-11 09:39 |只看该作者
gzip和deflate又不是同一种压缩格式。
你不管服务器是否返回了200,不管服务器是否采用了chunked传输,不管它的压缩格式是什么,直接用uncompress解压,怎么可能成功。

论坛徽章:
0
6 [报告]
发表于 2007-07-11 10:43 |只看该作者

回复 #5 福瑞哈哥 的帖子

谢谢你的提醒啊。
我想问问有没有相关的文档连接可以让我学习一下呢?
我是刚刚开始学习网络编程,所以很多问题不是很懂。^_^

论坛徽章:
0
7 [报告]
发表于 2007-07-11 10:48 |只看该作者
原帖由 tedli 于 2007-7-11 10:43 发表
谢谢你的提醒啊。
我想问问有没有相关的文档连接可以让我学习一下呢?
我是刚刚开始学习网络编程,所以很多问题不是很懂。^_^


gzip格式rfc 1952 http://www.ietf.org/rfc/rfc1952.txt
deflate格式rfc 1951 http://www.ietf.org/rfc/rfc1951.txt
zlib开发库 http://www.zlib.net/manual.html

论坛徽章:
0
8 [报告]
发表于 2007-08-07 16:41 |只看该作者
原帖由 福瑞哈哥 于 2007-7-11 09:39 发表
不管服务器是否采用了chunked传输

我加了一小段程序测试是不是chunked传输,但是没有反应,不知道是不是写错了?:
        if ((tmp = strstr(strResponse, CHUNKED)) == NULL)
            flag = 0;
        else
            flag = 1;
        if (flag == 1)
            printf ("find chunk");



即全程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <zlib.h>

#define BUFSIZE 10240
#define CHUNKED "Transfer-Encoding: chunked\r\n"
#define DestIp "58.61.166.67"
#define DestPort 80
#define Req "GET /cgi-bin/qqshow_user_searchitem?search_str=搞怪&style=1&nowpage=1&sorttype=0&content=&sex=0 HTTP/1.1\r\nAccept: */*\r\nAccept-Language: zh-cn\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\r\nHost: 58.61.166.67\r\nConnection: Keep-Alive\r\nCookie: pvid=1250811316; edition=4m16.mail.qq.com; CCSHOW=0000; ruv=3715021559298\r\n\r\n"
#define ReqLen sizeof(Req)

int main(int argc, char *argv[])
{
    ssize_t i;
    int nRequestLen;
    int templen = 0;
    int flag = -1;
    char *tmp = NULL;
    int c;

    gzFile file, zip;
    Byte compr[BUFSIZE], uncompr[BUFSIZE];
    uLong comprLen, uncomprLen;

    char strResponse[BUFSIZE]={0};
    char strRequest[BUFSIZE]={0};
    char strGzip[BUFSIZE]={0};
    char *pA = NULL;


    int sockfd, numbytes;
    struct sockaddr_in dest_addr; /* connector's address information */

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    dest_addr.sin_family = AF_INET; /* host byte order */
    dest_addr.sin_port = htons(DestPort); /* short, network byte order */
    dest_addr.sin_addr.s_addr = inet_addr(DestIp);

    /* Create and setup the connection */
    if (connect(sockfd, (struct sockaddr *)&dest_addr,sizeof(struct sockaddr)) == -1) {
        perror("connect");
        exit(1);
          }

    /* Send the request */
    strncpy(strRequest, Req,ReqLen);
    nRequestLen = ReqLen;
    if (write(sockfd,strRequest,nRequestLen) == -1) {
    perror("write");
    exit(1);
    }
    /* Read in the response */
    while(1) {
        i = read(sockfd,strResponse + templen,BUFSIZE-1);
        if(0 >= i){
            break;
        }
        //strResponse='\0';
        templen = templen + i;
    }
        printf(strResponse);
        pA = strstr(strResponse, "\r\n\r\n");
        if ((tmp = strstr(strResponse, CHUNKED)) == NULL)
            flag = 0;
        else
            flag = 1;
        if (flag == 1)
            printf ("find chunk");

        printf("%d\n", templen);
        printf("%d\n", pA - strResponse);
        printf(pA);

        memcpy(strGzip, pA + 4, templen - ((pA - strResponse) + 4));
        printf("\nooooooo\n");

        //gzprintf(file, strGzip);

        //comprLen = sizeof(file) / sizeof(compr[0]);
        comprLen = (templen - ((pA - strResponse) +4));
        printf("%d\n", comprLen);

        //strcpy((char *)uncompr, "garbage");
        /*int err = uncompress(uncompr, &uncomprLen, (const Bytef*)strGzip, comprLen);
        if (err != Z_OK){
            printf("uncompress error:%d\n", err);
            exit(1);
        }*/
       
    /* Close the connection */
    close(sockfd);
}

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
9 [报告]
发表于 2007-08-07 16:50 |只看该作者
到底是 http 失败,还是 gzip 解压失败啊?
这都搞不清,还能干什么?

论坛徽章:
0
10 [报告]
发表于 2007-08-07 17:07 |只看该作者
原帖由 tedli 于 2007-8-7 16:41 发表

我加了一小段程序测试是不是chunked传输,但是没有反应,不知道是不是写错了?:



即全程序如下:


你的程序错误的地方目前看来还是比较多的。
  while(1) {
        i = read(sockfd,strResponse + templen,BUFSIZE-1);
}这个循环有可能在很长时间内都不会结束,如果你一定要这样循环,把请求头中的Connection: Keep-Alive改成Connection: close
而且每次用BUFSIZE-1有可能造成内存越界。
你用strstr查找CHUNKED时,要先把某个位置设为字符串结束位置,设为'\0'
事实上你不应该查找CHUNKED,你应该先对协议头的每一行查找Transfer-Encoding: ,然后再比较它的值是不是chunked,应该是用strncasecmp,大小写不分的。

综上,建议使用libcurl库。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP