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

有同学会疑问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 "\r\n"

//定义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!\n");
        return 0;

}

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

i++;

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

}

}

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

i++;

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

}

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

}

if(flag1)
    {
        if(flag2)
        {
            *flag2='\0';
        }
        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!\n");
        return 0;

}

if(path==NULL)
    {
        printf("path is null!\n");
        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!\n");
        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\r\n");
        }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\n",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!\n");
        return 0;
    }

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

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

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

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

linux c使用socket进行http 通信,并接收任意大小的http响应(二)的更多相关文章

  1. linux c使用socket进行http 通信,并接收任意大小的http响应(三)

    使用socket进行http通信的时候,浏览器返回的响应经常不是固定长度的,有时候很大,有些时候又非常小,十分讨厌.如果仅仅只是为了接收一小段信息,设置一个十分大的缓存,这样又会十分浪费.而且经常更改 ...

  2. linux c使用socket进行http 通信,并接收任意大小的http响应(四)

    终于说到SOCKET 这里了.SOCKET进行http通信的实际就是利用socket将http请求信息发送给http服务器,然后再利用socket接收http响应. 由于本文与之通信的服务器是ip已知 ...

  3. linux c使用socket进行http 通信,并接收任意大小的http响应(一)

    如何进行http通信呢?我们打开任意一个浏览器,按F12,再选择网络,然后打开任意一个网站,我们就可以看到浏览器和网站通信的过程 如下图: 然后,我们任意点击一条记录,可以看到 然后,查找http协议 ...

  4. linux c使用socket进行http 通信,并接收任意大小的http响应(五)

    http.c data2.c http_url.c http.h data2.h http_url.h主要实现的功能是通过URL结构体来实现HTTP通信,你可以把这三个文件独立出来,作为HTTP通信模 ...

  5. c++ 网络编程(一)TCP/UDP windows/linux 下入门级socket通信 客户端与服务端交互代码

    原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9601511.html c++ 网络编程(一)TCP/UDP  入门级客户端与服务端交互代码 网 ...

  6. 基于ARM9和嵌入式Linux系统的多功能综合通信控制系统的框架

    基于ARM9硬件平台和嵌入式Linux系统的多功能综合通信控制系统的框架设计及各模块的功能.系统采用符合POSIX.1标准的C语言编写,实现了对下位机传送数据帧的采集.分析和存储,并能根据上位机的配置 ...

  7. LINUX 下 ipv6 socket 编程

    大家都知道,随着互联网上主机数量的增多,现有的32位IP地址已经不够用了,所以推出了下一代IP地址IPv6,写网络程序的要稍微改变一下现有的网络程序适应IPv6网络是相当容易的事.对于我们来说就是IP ...

  8. linux各种IPC机制(进程通信)

    linux各种IPC机制 (2011-07-08 16:58:35)      原文地址:linux各种IPC机制(转)作者:jianpengliu 原帖发表在IBM的developerworks网站 ...

  9. Linux学习之socket编程(二)

    Linux学习之socket编程(二) 1.C/S模型——UDP UDP处理模型 由于UDP不需要维护连接,程序逻辑简单了很多,但是UDP协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实 ...

随机推荐

  1. Kaggle比赛:从何着手?

    介绍 参加Kaggle比赛,我必须有哪些技能呢? 你有没有面对过这样的问题?最少在我大二的时候,我有过.过去我仅仅想象Kaggle比赛的困难度,我就感觉害怕.这种恐惧跟我怕水的感觉相似.怕水,让我无法 ...

  2. Solr数据迁移

    单机Solr部署在linux /opt目录下,运行一段时间后发现该目录分配的空间不足,而Solr的索引数据量较大,必须更改相关core下面的data目录,以改变索引存放的目录. 找到相应的solrco ...

  3. Flask最强攻略 - 跟DragonFire学Flask - 第十六篇 Flask-Migrate

    终于到了Flask-Migrate,之前在学习Flask-SQLAlchemy的时候,有的同学就提过类似的问题,Flask支持 makemigration / migrate 吗? 答案在这里该诉你, ...

  4. [转载]Javascript .then()这个方法是什么意思?

    then()方法是异步执行. 意思是:就是当.then()前的方法执行完后再执行then()内部的程序,这样就避免了,数据没获取到等的问题. 语法:promise.then(onCompleted, ...

  5. vue运行时 eslint 报“import/first” WARN deprecated browserslist 问题解决

    vue运行时 eslint 报“import/first”  WARN deprecated browserslist 问题解决 这个信息的意思是导入文件顺序不对,绝对导入应该放在相对导入前面.将绝对 ...

  6. Java访问权限修饰符public protected friendly private用法总结(转载好文Mark)

    首先声明:Java中,friendly这个修饰符并没有显式的声明,在成员变量和方法前什么修饰符也不用,默认的就是friendly.为了条理清晰,分三种不同情况来总结. 一 访问权限修饰符修饰成员变量和 ...

  7. 启动docker容器时的Error response from daemon: devmapper: Error mounting: invalid argument. 错误解决

    错误出现 在一台物理机重启后,以前创建的容器无法启动了.一启动,则会报出错误. [root@217TN1V ~]# docker start e7e Error response from daemo ...

  8. 【Alpha】Scrum Meeting 1

    前言 第1次会议在3月17日由PM在教一317召开. 主要确定了选题,并对目标进行了初步的确定.时长90min. 任务分配 姓名 当前阶段任务 下阶段任务 吴昊 确定项目方向,本地部署代码,完成团队介 ...

  9. Linux系统组成

     1 系统组成 BootLoader:操作系统引导程序 内核: 文件系统:应用程序(用户开发的.网上下载的) 2 安装USB驱动 dongry@d-linux:~$ insmod usb_dnw.ko ...

  10. DDD 之 Multiple Canonical Models

    MultipleCanonicalModels Scratch any large enterprise and you'll usually find some kind of group focu ...