編寫自己的WEB服務端http_client 源代碼

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include "http_client.h"
#define BUFFER_SIZE 1024
int http_client_create(http_client *pclient,const char *host, int port)
{
struct hostent *he;
if(pclient == NULL)
return -1;
memset(pclient,0,sizeof(http_client));
#ifdef WIN32
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif  /*  WIN32  */
if((he = gethostbyname(host))==NULL)
{
int err = WSAGetLastError();
printf("%d",err);
return -2;
}
pclient->remote_port = port;
strcpy(pclient->remote_ip,inet_ntoa( *((struct in_addr *)he->h_addr)));
pclient->_addr.sin_family = AF_INET;
pclient->_addr.sin_port = htons(pclient->remote_port);
pclient->_addr.sin_addr = *((struct in_addr *)he->h_addr);
if((pclient->socket = socket(AF_INET,SOCK_STREAM,0))==-1)
{
return -3;
}
/*TODO:是否應該釋放內存呢?*/
return 0;
}
int http_client_conn(http_client *pclient)
{
if(pclient->connected)
return 1;
if(connect(pclient->socket, (struct sockaddr *)&pclient->_addr,sizeof(struct sockaddr))==-1)
{
#ifdef WIN32
WSACleanup();
#endif
return -1;
}
pclient->connected = 1;
return 0;
}

int http_client_recv(http_client *pclient,char **lpbuff,int size)
{
int recvnum=0,tmpres=0;
char buff[BUFFER_SIZE];
*lpbuff = NULL;
while(recvnum < size || size==0)
{
tmpres = recv(pclient->socket, buff,BUFFER_SIZE,0);
if(tmpres <= 0)
break;
recvnum += tmpres;
if(*lpbuff == NULL)
{
*lpbuff = (char*)malloc(recvnum);
if(*lpbuff == NULL)
return -2;
}
else
{
*lpbuff = (char*)realloc(*lpbuff,recvnum);
if(*lpbuff == NULL)
return -2;
}
memcpy(*lpbuff+recvnum-tmpres,buff,tmpres);
}
return recvnum;
}
int http_client_send(http_client *pclient,char *buff,int size)
{
int sent=0,tmpres=0;
while(sent < size)
{
tmpres = send(pclient->socket,buff+sent,size-sent,0);
if(tmpres == -1)
{
return -1;
}
sent += tmpres;
}
return sent;
}
int http_client_close(http_client *pclient)
{
closesocket(pclient->socket);
pclient->connected = 0;
return 0;
}
int http_post(http_client *pclient,char *page,char *request,char **response)
{
char post[300],host[100],content_len[100];
char *lpbuf,*ptmp;
int len=0;
lpbuf = NULL;
const char *header2="User-Agent: linux_http_client Http 1.0\r\nCache-Control: no-cache\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: */*\r\n";
sprintf(post,"GET %s HTTP/1.0\r\n",page);
sprintf(host,"HOST: %s:%d\r\n",pclient->remote_ip,pclient->remote_port);
sprintf(content_len,"Content-Length: %d\r\n\r\n",strlen(request));
len = strlen(post)+strlen(host)+strlen(header2)+strlen(content_len)+strlen(request);
lpbuf = (char*)malloc(len);
if(lpbuf==NULL)
{
#ifdef WIN32
WSACleanup();
#endif
return -1;
}
strcpy(lpbuf,post);
strcat(lpbuf,host);
strcat(lpbuf,header2);
strcat(lpbuf,content_len);
strcat(lpbuf,request);
if(!pclient->connected)
{
http_client_conn(pclient);
}
if(http_client_send(pclient,lpbuf,len)<0)
{
return -1;
}
printf("發送請求:\n%s\n",lpbuf);
/*釋放內存*/
/*it's time to recv from server*/
memset(lpbuf,0,len);
if(http_client_recv(pclient,&lpbuf,0) <= 0)
{
if(lpbuf) free(lpbuf);
return -2;
}
memset(post,0,sizeof(post));
strncpy(post,lpbuf+9,3);
printf("返回碼: %d\n",atoi(post));
printf("接收響應:\n%s\n",lpbuf);
/*響應代碼,|HTTP/1.0 200 OK|
*從第10個字符開始,第3位
* */
ptmp = (char*)strstr(lpbuf,"\r\n\r\n");
if(ptmp == NULL)
{
free(lpbuf);
return -3;
}
ptmp += 4;/*跳過\r\n*/
len = strlen(ptmp)+1;
*response=(char*)malloc(len);
if(*response == NULL)
{
if(lpbuf) free(lpbuf);
return -1;
}
memset(*response,0,len);
memcpy(*response,ptmp,len-1);
/*從頭域找到內容長度,如果沒有找到則不處理*/
ptmp = (char*)strstr(lpbuf,"Content-Length:");
if(ptmp != NULL)
{
char *ptmp2;
ptmp += 15;
ptmp2 = (char*)strstr(ptmp,"\r\n");
if(ptmp2 != NULL)
{
memset(post,0,sizeof(post));
strncpy(post,ptmp,ptmp2-ptmp);
if(atoi(post)<len)
(*response)[atoi(post)] = '\0';
}
}
if(lpbuf) free(lpbuf);
return 0;
}
int http_get(http_client *pclient,char *page,char **response)
{
char post[300],host[100],header2[1024];
char *lpbuf,*ptmp;
int len=0;
lpbuf = NULL;
memset(header2,0,1024);
sprintf(header2,"Connection: keep-alive\r\nAccept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,p_w_picpath/png,*/*;q=0.5\r\nUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.33 Safari/534.3 SE 2.X MetaSr 1.0\r\nAccept-Encoding: gzip,deflate\r\nAccept-Language: zh-CN,zh;q=0.8\r\nAccept-Charset: GBK,utf-8;q=0.7,*;q=0.3\r\nCookie: prov=86; city=other; weather_city=bj; userid=1306844325031_5716; ilocid=1000; ilocidflag=1; vjuids=60f761c9e.13045fde8be.0.427b2991; iCast2_15963_2105hO=0_2_20160; _iCast2_15963_2105hO=2; Q37_sid=U4Bb45; ExpendBuoywwwpacx2011619=1; vjlast=1306844326.1308468360.11; Q37_visitedfid=442D284\r\nIf-Modified-Since: Sun, 19 Jun 2011 11:27:13 GMT\r\n\r\n");
sprintf(post,"GET %s HTTP/1.1\r\n",page);
sprintf(host,"Host: %s:%d\r\n",pclient->remote_ip,pclient->remote_port);
len = strlen(post)+strlen(host)+strlen(header2);
lpbuf = (char*)malloc(len);
if(lpbuf==NULL)
{
#ifdef WIN32
WSACleanup();
#endif
return -1;
}
strcpy(lpbuf,post);
strcat(lpbuf,host);
strcat(lpbuf,header2);
if(!pclient->connected)
{
http_client_conn(pclient);
}
if(http_client_send(pclient,lpbuf,len)<0)
{
return -1;
}
printf("發送請求:\n%s\n",lpbuf);
/*釋放內存*/
/*it's time to recv from server*/
memset(lpbuf,0,len);
if(http_client_recv(pclient,&lpbuf,0) <= 0)
{
if(lpbuf) free(lpbuf);
return -2;
}
memset(post,0,sizeof(post));
strncpy(post,lpbuf+9,3);
printf("返回碼: %d\n",atoi(post));
printf("接收響應:\n%s\n",lpbuf);
/*響應代碼,|HTTP/1.0 200 OK|
*從第10個字符開始,第3位
* */
ptmp = (char*)strstr(lpbuf,"\r\n\r\n");
if(ptmp == NULL)
{
free(lpbuf);
return -3;
}
ptmp += 4;/*跳過\r\n*/
len = strlen(ptmp)+1;
*response=(char*)malloc(len);
if(*response == NULL)
{
if(lpbuf) free(lpbuf);
return -1;
}
memset(*response,0,len);
memcpy(*response,ptmp,len-1);
/*從頭域找到內容長度,如果沒有找到則不處理*/
ptmp = (char*)strstr(lpbuf,"Content-Length:");
if(ptmp != NULL)
{
char *ptmp2;
ptmp += 15;
ptmp2 = (char*)strstr(ptmp,"\r\n");
if(ptmp2 != NULL)
{
memset(post,0,sizeof(post));
strncpy(post,ptmp,ptmp2-ptmp);
if(atoi(post)<len)
(*response)[atoi(post)] = '\0';
}
}
if(lpbuf) free(lpbuf);
return 0;
}
int main()
{
http_client client;
char *response = NULL;
char url[256];
printf("Input the URL:");
scanf("%s",url);
printf("開始組包\n");
http_client_create(&client,url,80);
if(http_post(&client,"/"," ",&response))
{
printf("失敗!\n");
exit(2);
}
/*    if(http_get(&client,"/",&response))
{
printf("失敗!\n");
exit(2);
}
*/
printf("響應:\n%d:%s\n",strlen(response),response);
FILE *fp;
fp = fopen("index.html","w");
fwrite(response,strlen(response),1,fp);
fclose(fp);
free(response);
#ifdef WIN32
WSACleanup();
#endif
return 0;
}

http_client.h

#ifndef _LINUX_HTTP_CLIENT_
#define _LINUX_HTTP_CLIENT_

#ifdef WIN32
#include <Winsock2.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#define closesocket close
#endif
typedef struct linux_http_client{
int socket;
int remote_port;
char remote_ip[16];
struct sockaddr_in _addr;
int connected;
} http_client;
int http_client_create(http_client *,const char *host, int port);
int http_client_conn(http_client *);
int http_client_recv(http_client *,char **lpbuff,int size);
int http_client_send(http_client *,char *buff,int size);
int http_client_close(http_client *);
#endif

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章