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协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实 ...
随机推荐
- 谷歌PM面试官告诉你,如何成功拿到理想offer
快来看看大咖Nick如何甄选人才~文章转自墨刀公众号. 本文作者: Nick Baum,目前在谷歌做PM 作为谷歌的产品经理和面试官,我已经面过几百个PM的候选人了吧.这些经历能让我分享一下在PM求职 ...
- linux delete file
今天不小心生成了这么个文件名的文件-ep-ser 然后 rm -ep-ser就删除不了,它认为-e是option 后来,用rm ./-ep-ser就顺利删除了,哈哈,教训啊
- ArchLinux安装Sublime Text 3
安装方法: 在 /etc/pacman.conf中添加 [archlinuxcn] SigLevel = Optional TrustAll Server = http://repo.archlinu ...
- CentOS 7 开机延迟解决办法
遇到这种情况 , 开机延迟 , 可以用下面的办法来查看 , 寻找到问题的源头 , 来看看到的是怎么回事 [root@DaMoWang ~]# dmesg |grep udev #显示系统的启动信息 ...
- GDscript风格指南
(惯例感谢godot开发组~~·) 缩进 缩进类型:Tabs (编辑器默认) 缩进大小:4 (编辑器默认) 每个缩进级别必须大于包含它的代码块. 良好的: for i in range(10): pr ...
- redis解决高并发下脏读问题
//解决并发情况下卡脏读的问题 protected function BingFa($mobile, $ent_id){ $obj = EnterpriseMembers::getNewMemberC ...
- q次询问,每次给一个x,问1到x的因数个数的和。
q次询问,每次给一个x,问1到x的因数个数的和. #include<cmath> #include<cstdio> #include<cstring> usingn ...
- Vue用axios跨域访问数据
Vue用axios跨域访问数据axios是vue-resource的替代品,vue-resource不再维护.安装axios:npm install axios使用vue-cli开发时,由于项目本身启 ...
- Linux(5.5版为主)的基本操作命令
mount 查看挂载目录 cat ~ 查看文件下的内容 touch ~ 创建一个文件 一次性性创建几个文件: touch /tmp/{1,2,3,4}.txt ...
- 51Nod 1174 区间中最大的数
给出一个有N个数的序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,最大的数是多少. 例如: 1 7 6 3 1.i = 1, j = 3,对应的数为7 6 3,最大的数为7. ...