zoukankan      html  css  js  c++  java
  • 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! ");
            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! ");
            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! ");
            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! ");
            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! ");
            return NULL;
        }
        i=count_Buffer_Node(header);
        result=(char*)malloc((i+100)*sizeof(char));
        memset(result,'',i*sizeof(char));

        nowNode=header;

        while(nowNode->next!=NULL)
        {
            nowNode=nowNode->next;
            strcat(result,nowNode->data);
        }
        printf(" result is:%s ",result);
        return result;

    }

    当然,我只是考虑到功能的实现,并未考虑到效率的问题。

  • 相关阅读:
    微信小程序HTTPS
    微信商城-1简介
    va_list
    Event log c++ sample.
    EVENT LOGGING
    Analyze Program Runtime Stack
    unknow table alarmtemp error when drop database (mysql)
    This application has request the Runtime to terminate it in an unusual way.
    How to check if Visual Studio 2005 SP1 is installed
    SetUnhandledExceptionFilter
  • 原文地址:https://www.cnblogs.com/thegodofthunder/p/7216328.html
Copyright © 2011-2022 走看看