linux c使用socket进行http 通信,并接收任意大小的http响应(三)
使用socket进行http通信的时候,浏览器返回的响应经常不是固定长度的,有时候很大,有些时候又非常小,十分讨厌。如果仅仅只是为了接收一小段信息,设置一个十分大的缓存,这样又会十分浪费。而且经常更改缓存大小的话,也不太好。
为了能够接收任意大小的响应,我程序的流程大概是这样子的:
(1)将SOCKET接收的信息保存到一个动态分配内存的链表里。链表每个节点存储有固定字节大小的HTTP响应,每当一个节点存储满,就继续添加一个新的节点继续缓存;
(2)接收信息结束后,将存储在链表当中的HTTP响应全部取出,合并,放到一个统一的动态内训空间中。
与链表有关的函数如下:
(1)data2.h
//声明在其他程序当中可能用到data2.c的函数
#ifndef textbuffer_h
#define textbuffer_h
struct textbuffer
{
char data[52224];
struct textbuffer *next;
};
typedef struct textbuffer TEXTBUFFER,*PBUFFER;
extern PBUFFER create_EmptyBufferLink();
extern PBUFFER create_EmptyBuffer();
extern PBUFFER append_Buffer_Node(PBUFFER header);
extern int free_Buffer_Link(PBUFFER header);
extern unsigned long count_Buffer_Node(PBUFFER header);
extern char* get_All_Buffer(PBUFFER header);
#endif // textbuffer_h
(2)data2.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//定义节点结构体用于缓存HTTP响应
//textbuffer_h表示已经定义了textbuffer结构体(防止重复定义)
#define textbuffer_h
struct textbuffer
{
char data[52224];
struct textbuffer *next;
};
typedef struct textbuffer TEXTBUFFER,*PBUFFER;
//创建头节点
//返回值:成功返回指向动态内存指针,失败返回NULL
//注:1)创建头结点之后,注意检查头结点是否为空再使用;2)头结点的下一个结点才开始存储内容
PBUFFER create_EmptyBufferLink()
{
PBUFFER header;
header=(PBUFFER)malloc(sizeof(TEXTBUFFER));
if(header!=NULL)
{
memset(header,0,sizeof(TEXTBUFFER));
header->next=NULL;
}
return header;
}
//创建一个空的节点
//如果动态分配成功,局部变量node当中存有的是动态内存的地址,但是为防止极端情况(有人故意将可分配的动态空间占用完),还是改了一下代码
//返回值:成功返回指向动态内存指针,失败返回NULL
PBUFFER create_EmptyBuffer()
{
PBUFFER node;
if(NULL!=(node=(PBUFFER)malloc(sizeof(TEXTBUFFER))))
{
memset(node,0,sizeof(TEXTBUFFER));
node->next=NULL;
}
return node;
}
//向链表尾部添加节点,返回新添加节点的指针,节点的内容可以通过返回的节点指针向其添加
//注:注意检查新分配的节点是否为NULL
PBUFFER append_Buffer_Node(PBUFFER header)
{
PBUFFER newNode,nowNode;
if(header==NULL)
{
printf("header is null!\n");
return 0;
}
newNode=create_EmptyBuffer();
nowNode=header;
while(nowNode->next!=NULL)
{
nowNode=nowNode->next;
}
nowNode->next=newNode;
return newNode;
}
//清空除了头结点之外其他的所有节点
int empty_Buffer_Node(PBUFFER header)
{
PBUFFER nowNode,freeNode;
if(header==NULL)
{
printf("header is null!\n");
return 0;
}
nowNode=header;
nowNode=nowNode->next;
while(nowNode!=NULL)
{
freeNode=nowNode;
nowNode=nowNode->next;
free(freeNode);
}
header->next=NULL;
return 1;
}
//清空包括头结点在内的所有节点
int free_Buffer_Link(PBUFFER header)
{
if(header==NULL)
{
printf("header is null!\n");
return 0;
}
empty_Buffer_Node(header);
free(header);
header=NULL;
return 1;
}
//计算BUFFER链表一共存储了多少字节的响应,并且返回最终结果
unsigned long count_Buffer_Node(PBUFFER header)
{
PBUFFER nowNode;
unsigned long i=0;
if(header==NULL)
{
printf("header is null!\n");
return 0;
}
nowNode=header;
while(nowNode->next!=NULL)
{
nowNode=nowNode->next;
i+=strlen(nowNode->data);
}
return i;
}
//将整个BUFFER链表的内容提取出来,并存储到动态内存之中,返回动态内存的指针
//注:1)执行到此步,若是不再使用BUFFER链表,应用int free_Buffer_Link(PBUFFER header)释放链表
//2)返回的动态内存指针,若是不再使用动态内存里面的内容应通过free将其释放
char* get_All_Buffer(PBUFFER header)
{
unsigned long i;
PBUFFER nowNode;
char *result;
if(header==NULL)
{
printf("header is null!\n");
return NULL;
}
i=count_Buffer_Node(header);
result=(char*)malloc((i+100)*sizeof(char));
memset(result,'\0',i*sizeof(char));
nowNode=header;
while(nowNode->next!=NULL)
{
nowNode=nowNode->next;
strcat(result,nowNode->data);
}
printf("\nresult is:%s\n",result);
return result;
}
当然,我只是考虑到功能的实现,并未考虑到效率的问题。
linux c使用socket进行http 通信,并接收任意大小的http响应(三)的更多相关文章
- linux c使用socket进行http 通信,并接收任意大小的http响应(四)
终于说到SOCKET 这里了.SOCKET进行http通信的实际就是利用socket将http请求信息发送给http服务器,然后再利用socket接收http响应. 由于本文与之通信的服务器是ip已知 ...
- linux c使用socket进行http 通信,并接收任意大小的http响应(二)
先贴请求头部信息组织代码. 有同学会疑问http_url.h是干什么用的,我要在这里声明,http_url.h并不是给http_url.c用的,实际上http_url.h声明了http_url.c已经 ...
- linux c使用socket进行http 通信,并接收任意大小的http响应(一)
如何进行http通信呢?我们打开任意一个浏览器,按F12,再选择网络,然后打开任意一个网站,我们就可以看到浏览器和网站通信的过程 如下图: 然后,我们任意点击一条记录,可以看到 然后,查找http协议 ...
- linux c使用socket进行http 通信,并接收任意大小的http响应(五)
http.c data2.c http_url.c http.h data2.h http_url.h主要实现的功能是通过URL结构体来实现HTTP通信,你可以把这三个文件独立出来,作为HTTP通信模 ...
- c++ 网络编程(一)TCP/UDP windows/linux 下入门级socket通信 客户端与服务端交互代码
原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9601511.html c++ 网络编程(一)TCP/UDP 入门级客户端与服务端交互代码 网 ...
- 基于ARM9和嵌入式Linux系统的多功能综合通信控制系统的框架
基于ARM9硬件平台和嵌入式Linux系统的多功能综合通信控制系统的框架设计及各模块的功能.系统采用符合POSIX.1标准的C语言编写,实现了对下位机传送数据帧的采集.分析和存储,并能根据上位机的配置 ...
- LINUX 下 ipv6 socket 编程
大家都知道,随着互联网上主机数量的增多,现有的32位IP地址已经不够用了,所以推出了下一代IP地址IPv6,写网络程序的要稍微改变一下现有的网络程序适应IPv6网络是相当容易的事.对于我们来说就是IP ...
- linux各种IPC机制(进程通信)
linux各种IPC机制 (2011-07-08 16:58:35) 原文地址:linux各种IPC机制(转)作者:jianpengliu 原帖发表在IBM的developerworks网站 ...
- Linux学习之socket编程(二)
Linux学习之socket编程(二) 1.C/S模型——UDP UDP处理模型 由于UDP不需要维护连接,程序逻辑简单了很多,但是UDP协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实 ...
随机推荐
- pat 1051Pop Sequence
模拟栈的过程,一开始我是用的cin来判断每行的每一个数字,然后判断回车结束.有一个点会超时,答案用数组先记录序列的方法非常好.有一个注意点就是访问s.top()的时候先要保证s.size()>0 ...
- vue-awesome-swiper组件不能自动播放和导航器小圆点不显示问题
from: https://blog.csdn.net/osdfhv/article/details/79062427 <template> <div class="swi ...
- Python 第五阶段 学习记录之----ORM
ORM: orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却都是关系型的,为了 ...
- dubbo框架整合常见问题
逆向工程常见问题总结 tomcat7插件启动项目卡在:log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for ...
- Docker Overlay 工作原理
Docker 原生Overlay 网络工作流程 如图:有两个Container 独立的容器节点.他们通过Overlay网路进行通信. 网卡设备 Container eth0:eth0它是Overlay ...
- shell爬虫--抓取某在线文档所有页面
在线教程一般像流水线一样,页面有上一页下一页的按钮,因此,可以利用shell写一个爬虫读取下一页链接地址,配合wget将教程所有内容抓取. 以postgresql中文网为例.下面是实例代码 #!/bi ...
- 【Maven】 Eclipse使用Maven创建Java Web 项目(一)
需求:创建一个Servlet版本3.0,Java版本是1.7的Maven Web项目 创建环境: 系统:window 7 软件:Eclipse.Maven 创建步骤: 1.使用eclipse工具创建m ...
- Bugku-CTF之输入密码查看flag
Day14 输入密码查看flag http://123.206.87.240:8002/baopo/
- Linux统计文件中单词出现的次数
grep -E "\b[[:alpha:]]+\b" /etc/fstab -o | sort | uniq -c 或 awk '{for(i=1;i<NF;i++){c ...
- linux(centos)测试带宽
1.安装speedtest-cli speedtest-cli是一个用Python编写的轻量级Linux命令行工具,在Python2.4至3.4版本下均可运行.它基于Speedtest.net的基础架 ...