標籤:strcat 儲存 節點 bsp 重複 其他 檢查 str 結構體
使用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響應(三)