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协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实 ...
随机推荐
- Maven pom.xml详解(转)
pom文件总体结构 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...
- AES,BigInteger,MD5加密
http://tool.oschina.net/apidocs/apidoc?api=jdk-zh package cn.com.gome.cashier.web; import java.lang. ...
- chrome内核浏览器插件的使用--Tampermonkey(油猴插件)
Tampermonkey(油猴插件),这个插件是一个用于改造你浏览器打开的网站的插件.它可以在你打开的网页中注入任意js脚本,以达到你想要的外加功能.可以说非常不错.很多时候也值得使用. 这是个chr ...
- angular7 DOM操作 及 @ViewChild
一.Angular 中的 dom 操作(原生 js) 二.Angular 中的 dom 操作(ViewChild) 三.父子组件中通过 ViewChild 调用子组件 的方法 1.调用子组件给子组件定 ...
- 剑指offer(4)重建二叉树
题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...
- 剑指offer(50)数组中重复的数字
题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
- Java基础学习-HelloWorld案例的编写和运行
一.HelloWorld案例的流程: 第一步:编写一个.java的源文件.通过Windows自带的记事本文件就可以完成. 第二步:将.java的源文件通过编译器编译生成 ...
- Linux下Shell的for循环语句
第一类:数字性循环-----------------------------for1-1.sh #!/bin/bash ;i<=;i++)); do + ); done ------------ ...
- Intellij IDEA 修改默认配置
更新IDEA,是配置无缝对接 idea里面的配置文件主要就idea64.exe.vmoptions,idea.properties 不要更新idea自带的这两个文件,因为在更新IntelliJ IDE ...
- C# winform 选择文件保存路径
1.winform 点击按钮选择文件保存的路径,效果如下图: 具体代码如下: private void button8_Click(object sender, EventArgs e) { Fold ...