首页 > 代码库 > linux c使用socket进行http 通信,并接收任意大小的http响应(三)

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响应(三)