zoukankan      html  css  js  c++  java
  • linux c使用socket进行http 通信,并接收任意大小的http响应(二)

    先贴请求头部信息组织代码.

    有同学会疑问http_url.h是干什么用的,我要在这里声明,http_url.h并不是给http_url.c用的,实际上http_url.h声明了http_url.c已经编写好的函数,这样当我们想要在其他c文件使用http_url.c文件的函数的时候就不必将http_url.c文件中的内容整个复制过去,只要包含http_url.h头文件,然后再和http_url.c文件一起编译即可,请搜索linux c 如何同时编译多个文件。

    还有同学会问#ifndef http_url_h #define http_url_h这些东西是什么鬼?这是因为,我们有些时候会不小心将同一个头文件重复包含,像结构体和全局变量的声明一旦重复包含的话,编译器就会报错,我这样做的原因就是为了防止头文件被重复包含

    一、http_url.h

    #ifndef http_url_h
    #define http_url_h

    struct post_data
    {
        char postData[10*1024];

    };
    typedef struct post_data PostData ,*PostData_pointer;

    struct url
    {
        char url[500];
        PostData postData;
    };

    typedef struct url URL,*PURL;
    extern char cookie[100];
    extern int parse_url(char *host,char *path,char *url);
    extern int organize_url(char *url,char *host,char *path);
    extern int http_request(char *request,PURL url);
    extern void num_to_string(char *str,int i);
    extern int Init_URL(PURL Purl,char *url,char *postData);
    #endif

    二、http_url.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #define ACCEPT_ALL "*/*"
    #define ACCEPT_HTML "text/html"
    #define ACCEPT_JSON "applicaton/json"
    #define CONTENT_NORMAL "application/x-www-form-urlencoded"
    #define CONTENT_MULTI "multipart/form-data"
    #define CRIL " "

    //定义http_url_h,为防止重复定义
    #define http_url_h
    void num_to_string(char *str,int i);

    //定义结构体,用于存储要POST的数据
    struct post_data
    {
        char postData[10*1024];

    };

    typedef struct post_data PostData ,*PostData_pointer;

    //定义结构体,用于存储HTTP通信所需的URL和要POST给URL的数据
    //例如:url->url="http://192.168.6.1",url->postData->postData="name=you&id=123"
    struct url
    {
        char url[500];
        PostData postData;
    };

    typedef struct url URL ,*PURL;

    //全局变量cookie,登录操作之后通过find_cookie可得
    char cookie[100];

    //将URL中的HOST和PATH部分分离
    //参数一:存储HOST的字符串
    //参数二:存储PATH的字符串
    //参数三:将被分解的URL
    //返回值:成功返回1,失败返回0
    int parse_url(char *host,char *path,char *url)
    {
        int i=0,j=0;
        char *flag1,*flag2;
        char temp[200];
        strcpy(temp,url);

        if(url==NULL)
        {
            printf("url is null! ");
            return 0;

        }

        while(temp[i]!='')
        {
            if(temp[i]=='/')
            {
                j++;
            }

            i++;



            if(j==3)
            {
                flag2=&temp[i-1];
                break;

            }

        }

        i=0;
        j=0;
         while(temp[i]!='')
        {
            if(temp[i]=='/')
            {
                j++;
            }

            i++;

            if(j==2)
            {
                flag1=(&temp[i]);
                break;
            }


        }


        if(flag2)
        {
            strcpy(path,flag2);


        }


        if(flag1)
        {
            if(flag2)
            {
                *flag2='';
            }
            strcpy(host,flag1);

            return 1;

        }else
        {
            return 0;

        }


    }

    //将HOST和PATH部分组成一个完整的URL
    //参数一:存储组织完成后的URL
    //参数二:存储HOST的字符串
    //参数三:存储PATH的字符串
    //返回值:成功返回1,失败返回0
    int organize_url(char *url,char *host,char *path)
    {
        char temp[200];
         if(host==NULL)
        {
            printf("host is null! ");
            return 0;

        }

         if(path==NULL)
        {
            printf("path is null! ");
            return 0;

        }

        strcpy(temp,"http://");
        strcat(temp,host);
        strcat(temp,path);

        strcpy(url,temp);

        return 1;

    }

    //根据传入已经初始化的URL结构体,组织HTTP REQUEST头部
    //参数一:存储经组织后的HTTP REQUEST头部的字符串指针
    //参数二:存储有URL和要POST给URL的数据(不一定有)的URL结构体
    //返回值:成功返回1,失败返回0
    int http_request(char *request,PURL url)
    {
        char temp[70000];
        char host[100];
        char path[200];
        char content_length[20];

        if(url==NULL)
        {

            printf("url is null");
            return 0;
        }

        if(strlen(url->postData.postData)>5)//当有数据POST给URL的时候使用POST方法,否则使用GET方法
        {

            strcpy(temp,"POST ");

        }else
        {
            strcpy(temp,"GET ");

        }

        if(parse_url(host,path,url->url))//将完整URL的HOST和PATH部分分解
        {
            if(strlen(path)!=0)
            {

                strcat(temp,path);
                strcat(temp," ");

            }


        }else
        {

            printf("url not exsist! ");
            return 0;

        }

        strcat(temp,"HTTP/1.0");
        strcat(temp,CRIL);
        strcat(temp,"Host: ");
        strcat(temp,host);
        strcat(temp,CRIL);

        if(strlen(cookie)>10)
        {
            strcat(temp,"Cookie: ");
            strcat(temp,cookie);
            strcat(temp,CRIL);

        }


        strcat(temp,"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        strcat(temp,CRIL);

        strcat(temp,"Connection: close");//使用close的原因是,在使用socket进行通信的时候,选择keep-alive响应特别慢
        strcat(temp,CRIL);

        strcat(temp,"Upgrade-Insecure-Requests: 1");
        strcat(temp,CRIL);

        strcat(temp,"Accept-Encoding: gzip, deflate");
        strcat(temp,CRIL);

        strcat(temp,"Accept-Language: en-US,en;q=0.5");
        strcat(temp,CRIL);

        if(strlen(url->postData.postData)>5)//当有数据POST给URL的时候,带上POST的数据
        {
            strcat(temp,"Content-Type: ");
           
            if(strstr(url->postData.postData,"------"))//检查是不是multipart date 数据
            {
                strcat(temp,CONTENT_MULTI);//注意:CONTENT_NORMAL和CONTENT_MULTI不是变量,是宏定义!!!!好吧,原本是小写的,现在我已经改了
                strcat(temp,"; boundary=");
                strcat(temp,"------WebKitFormBoundaryaoOeFzIPZu3yeBWJ ");
            }else
            {
                strcat(temp,CONTENT_NORMAL);
                strcat(temp,CRIL);

            }

            strcat(temp,"Content-Length: ");
            num_to_string(content_length,strlen(url->postData.postData));
            strcat(temp,content_length);
            strcat(temp,CRIL);
            strcat(temp,CRIL);
            strcat(temp,url->postData.postData);


        }else
        {
            strcat(temp,CRIL);
            
        }

        printf("%s ",temp);

        strcpy(request,temp);
        return 1;
    }

    //URL结构体初始化函数
    //参数一:指向要被初始化的URL结构体的指针
    //参数二:完整的URL,如http://192.168.6.1/overview
    //参数三:要POST给URL的数据,可为NULL.当为NULL的时候,将初始化后的URL结构体给int http_request(char *request,PURL url)函数组织头部,会自动设置POST和GET方法
    int Init_URL(PURL Purl,char *url,char *postData)
    {
        if(url!=NULL)
        {
            strcpy(Purl->url,url);
        }
        else
        {
            printf("url is null! ");
            return 0;
        }

        if(postData!=NULL)
        {
            strcpy(Purl->postData.postData,postData);
        }else
        {
            strcpy(Purl->postData.postData,"");
        }

        return 1;
    }
    整个过程其实就是一顿字符串的组织和解析,最终的目的是为了组织出如下的头部,看起来很长,但是实际上没有什么技术含量。

    当组织成的头部大概是这个样子,在URL结构体postDate的数据为空的时候

    当在URL结构体postDate的数据不为空的时候,大概是这样

  • 相关阅读:
    win7下的vxworks总结
    ubuntu 无法获得锁 /var/lib/dpkg/lock
    项目中用到了的一些批处理文件
    win7下安装 WINDRIVER.TORNADO.V2.2.FOR.ARM
    使用opencv统计视频库的总时长
    January 05th, 2018 Week 01st Friday
    January 04th, 2018 Week 01st Thursday
    January 03rd, 2018 Week 01st Wednesday
    January 02nd, 2018 Week 01st Tuesday
    January 01st, 2018 Week 01st Monday
  • 原文地址:https://www.cnblogs.com/thegodofthunder/p/7216275.html
Copyright © 2011-2022 走看看