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协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实 ...
随机推荐
- Scala 偏函数
如果你想定义一个函数,而让它只接受和处理其参数定义域范围内的子集,对于这个参数范围外的参数则抛出异常,这样的函数就是偏函数(顾名思异就是这个函数只处理传入来的部分参数). 偏函数是个特质其的类型为Pa ...
- 自定义Word颜色主题
外观 说明 看到这个黑色编辑器的界面,第一印象可能认为是Sublime.Atom. VScode或者其它markdown编辑器.其实仅仅是微软的Word经过了自定义主题. 选择清晰易于辨认的字体和深色 ...
- <转>jmeter(二十二)内存溢出原因及解决方法
本博客转载自:http://www.cnblogs.com/imyalost/category/846346.html 个人感觉不错,对jmeter讲解非常详细,担心以后找不到了,所以转发出来,留着慢 ...
- 爬虫----BeautifulSoup模块
一.介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你 ...
- 一致性hash的实现
原文:https://blog.csdn.net/u011305680/article/details/79721030 1.不带虚拟节点的 package hash; import java.uti ...
- 如何利用cURL和python对服务端和web端进行接口测试
工具描述 cURL是利用URL语法在命令行方式下工作的文件传输工具,是开源爱好者编写维护的免费工具,支持包括Windows.Linux.Mac等数十个操作系统,最新版本为7.27.0,但是我推荐大家使 ...
- CentOS安装系统安装完成
一.安装centOS操作系统的相关步骤? 1)第一步:系统安装的方式,选择全新安装,第一行表示安装系统,第三行当用户名密码无法开机或密码忘记的时候启动 2)第二步:是否检查光盘,选择Skip跳过,没事 ...
- 进程池 和 multiprocessing.Pool模块
进程池的概念 在程序实际处理问题过程中,忙时会有成千上万的任务需要被执行,闲时可能只有零星任务.那么在成千上万个任务需要被执行的时候,我们就需要去创建成千上万个进程么?首先,创建进程需要消耗时间,销毁 ...
- 扩展的GM命令
命令 说明 例子 .rl all 重载核心所有自定义数据表 .rl item 重载item_template .backup a 备份Auth数据库 .backup c 备份Charact ...
- linux下postgres未能正常启动的解决过程
转载:http://www.cnblogs.com/starRebel/p/7892214.html 起因是一次linux服务器重启后,postgres没有起来,手动找原因. 1. 直接在命令行打po ...