首页
> C++
> 纯C++的Socket访问Http封装类
纯C++的Socket访问Http封装类
#include "stdafx.h"
#include <iostream>
#include <string>
#include "http\request.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
Request myRequest; //初始化类
string sHeaderSend; //定义http头
string sHeaderReceive; //返回头
string sMessage=""; //返回页面内容
bool IsPost=false; //是否Post提交
int i =myRequest.SendRequest(IsPost, "http://neeao.com", sHeaderSend,
sHeaderReceive, sMessage);
if (i)
{
cout<<"Http头:"<<endl;
cout<< sHeaderSend <<endl;
cout<<"响应头"<<endl;
cout<< sHeaderReceive <<endl;
cout<<"网页内容"<<endl;
cout<< sMessage <<endl;
}else
{
cout<<"网络不可到达"<<endl;
}
system("pause");
return 0;
}
直接上代码了,blog附件上传貌似有点问题,
Request.h
//******************************************
//纯C++的socket访问Http封装类,Neeao修改
//http://neeao.com
//2009-08-25
//******************************************
#if !defined(AFX_REQUEST_H__9F2C9BB6_CBA7_40AF_80A4_09A1CE1CE220__INCLUDED_)
#define AFX_REQUEST_H__9F2C9BB6_CBA7_40AF_80A4_09A1CE1CE220__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib, "WS2_32")
using namespace std;
#define MEM_BUFFER_SIZE 10
/*
HTTPRequest: Structure that returns the HTTP headers and message
from the request
*/
typedef struct
{
LPSTR headerSend; // Pointer to HTTP header Send
LPSTR headerReceive; // Pointer to HTTP headers Receive
LPSTR message; // Pointer to the HTTP message
long messageLength; // Length of the message
} HTTPRequest;
/*
MemBuffer: Structure used to implement a memory buffer, which is a
buffer of memory that will grow to hold variable sized
parts of the HTTP message.
*/
typedef struct
{
unsigned char *buffer;
unsigned char *position;
size_t size;
} MemBuffer;
class Request
{
public:
Request();
virtual ~Request();
private:
void MemBufferCreate(MemBuffer *b);
void MemBufferGrow(MemBuffer *b);
void MemBufferAddByte(MemBuffer *b, unsigned char byt);
void MemBufferAddBuffer(MemBuffer *b, unsigned char *buffer, size_t size);
DWORD GetHostAddress(LPCSTR host);
void SendString(SOCKET sock,LPCSTR str);
BOOL ValidHostChar(char ch);
void ParseURL(string url,LPSTR protocol,int lprotocol, LPSTR host,int lhost,LPSTR request,int lrequest,int *port);
int SendHTTP(string url,LPCSTR headerReceive,BYTE *post, DWORD postLength,HTTPRequest *req);
public:
int SendRequest(bool IsPost, string url, string& psHeaderSend, string& pszHeaderReceive,string& pszMessage);
};
#endif // !defined(AFX_REQUEST_H__9F2C9BB6_CBA7_40AF_80A4_09A1CE1CE220__INCLUDED_)
Request.cpp
//******************************************
//纯C++的Socket访问Http封装类,Neeao修改
//http://neeao.com
//2009-08-25
//******************************************
#include "stdafx.h"
#include "Request.h"
#include <string>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Request::Request()
{
}
Request::~Request()
{
}
//*******************************************************************************************************
//MemBufferCreate:
// Passed a MemBuffer structure, will allocate a memory buffer
// of MEM_BUFFER_SIZE. This buffer can then grow as needed.
//*******************************************************************************************************
void Request::MemBufferCreate(MemBuffer *b)
{
b->size = MEM_BUFFER_SIZE;
b->buffer =(unsigned char *) malloc( b->size );
b->position = b->buffer;
}
//*******************************************************************************************************
// MemBufferGrow:
// Double the size of the buffer that was passed to this function.
//*******************************************************************************************************
void Request::MemBufferGrow(MemBuffer *b)
{
size_t sz;
sz = b->position - b->buffer;
b->size = b->size *2;
b->buffer =(unsigned char *) realloc(b->buffer,b->size);
b->position = b->buffer + sz; // readjust current position
}
//*******************************************************************************************************
// MemBufferAddByte:
// Add a single byte to the memory buffer, grow if needed.
//*******************************************************************************************************
void Request::MemBufferAddByte(MemBuffer *b,unsigned char byt)
{
if( (size_t)(b->position-b->buffer) >= b->size )
MemBufferGrow(b);
*(b->position++) = byt;
}
//*******************************************************************************************************
// MemBufferAddBuffer:
// Add a range of bytes to the memory buffer, grow if needed.
//*******************************************************************************************************
void Request::MemBufferAddBuffer(MemBuffer *b,
unsigned char *buffer, size_t size)
{
while( ((size_t)(b->position-b->buffer)+size) >= b->size )
MemBufferGrow(b);
memcpy(b->position,buffer,size);
b->position+=size;
}
//*******************************************************************************************************
// GetHostAddress:
// Resolve using DNS or similar(WINS,etc) the IP
// address for a domain name such as www.wdj.com.
//*******************************************************************************************************
DWORD Request::GetHostAddress(LPCSTR host)
{
struct hostent *phe;
char *p;
phe = gethostbyname( host );
if(phe==NULL)
return 0;
p = *phe->h_addr_list;
return *((DWORD*)p);
}
//*******************************************************************************************************
// SendString:
// Send a string(null terminated) over the specified socket.
//*******************************************************************************************************
void Request::SendString(SOCKET sock,LPCSTR str)
{
send(sock,str,strlen(str),0);
}
//*******************************************************************************************************
// ValidHostChar:
// Return TRUE if the specified character is valid
// for a host name, i.e. A-Z or 0-9 or -.:
//*******************************************************************************************************
BOOL Request::ValidHostChar(char ch)
{
return( isalpha(ch) || isdigit(ch)
|| ch=='-' || ch=='.' || ch==':' );
}
//*******************************************************************************************************
// ParseURL:
// Used to break apart a URL such as
// http://www.localhost.com:80/TestPost.htm into protocol, port, host and request.
//*******************************************************************************************************
void Request::ParseURL(string url,LPSTR protocol,int lprotocol,LPSTR host,int lhost,LPSTR request,int lrequest,int *port)
{
char *work,*ptr,*ptr2;
*protocol = *host = *request = 0;
*port=80;
work = strdup(url.c_str());
strupr(work);
ptr = strchr(work,':'); // find protocol if any
if(ptr!=NULL)
{
*(ptr++) = 0;
lstrcpyn(protocol,work,lprotocol);
}
else
{
lstrcpyn(protocol,"HTTP",lprotocol);
ptr = work;
}
if( (*ptr=='/') && (*(ptr+1)=='/') ) // skip past opening /'s
ptr+=2;
ptr2 = ptr; // find host
while( ValidHostChar(*ptr2) && *ptr2 )
ptr2++;
*ptr2=0;
lstrcpyn(host,ptr,lhost);
lstrcpyn(request,url.c_str() + (ptr2-work),lrequest); // find the request
ptr = strchr(host,':'); // find the port number, if any
if(ptr!=NULL)
{
*ptr=0;
*port = atoi(ptr+1);
}
free(work);
}
//*******************************************************************************************************
// SendHTTP:
// Main entry point for this code.
// url - The URL to GET/POST to/from.
// headerSend - Headers to be sent to the server.
// post - Data to be posted to the server, NULL if GET.
// postLength - Length of data to post.
// req - Contains the message and headerSend sent by the server.
//
// returns 1 on failure, 0 on success.
//*******************************************************************************************************
int Request::SendHTTP(string url,LPCSTR headerReceive,BYTE *post,
DWORD postLength,HTTPRequest *req)
{
WSADATA WsaData;
SOCKADDR_IN sin;
SOCKET sock;
char buffer[512];
char protocol[20],host[256],request[1024];
int l,port,chars,err;
MemBuffer headersBuffer,messageBuffer;
char headerSend[1024];
BOOL done;
ParseURL(url,protocol,sizeof(protocol),host,sizeof(host), // Parse the URL
request,sizeof(request),&port);
if(strcmp(protocol,"HTTP"))
return 1;
err = WSAStartup (0x0101, &WsaData); // Init Winsock
if(err!=0)
return 1;
sock = socket (AF_INET, SOCK_STREAM, 0);
//if (socket == INVALID_SOCKET)
if (sock == INVALID_SOCKET)
{
return 1;
}
sin.sin_family = AF_INET; //Connect to web sever
sin.sin_port = htons( (unsigned short)port );
sin.sin_addr.s_addr = GetHostAddress(host);
if( connect (sock,(LPSOCKADDR)&sin, sizeof(SOCKADDR_IN) ) )
{
return 1;
}
if( !*request )
lstrcpyn(request,"/",sizeof(request));
if( post == NULL )
{
SendString(sock,"GET ");
strcpy(headerSend, "GET ");
}
else
{
SendString(sock,"POST ");
strcpy(headerSend, "POST ");
}
SendString(sock,request);
strcat(headerSend, request);
SendString(sock," HTTP/1.0\r\n");
strcat(headerSend, " HTTP/1.0\r\n");
SendString(sock,"Accept: image/gif, image/x-xbitmap,"
" image/jpeg, image/pjpeg, application/vnd.ms-excel,"
" application/msword, application/vnd.ms-powerpoint,"
" */*\r\n");
strcat(headerSend, "Accept: image/gif, image/x-xbitmap,"
" image/jpeg, image/pjpeg, application/vnd.ms-excel,"
" application/msword, application/vnd.ms-powerpoint,"
" */*\r\n");
SendString(sock,"Accept-Language: en-us\r\n");
strcat(headerSend, "Accept-Language: en-us\r\n");
SendString(sock,"Accept-Encoding: gzip, default\r\n");
strcat(headerSend, "Accept-Encoding: gzip, default\r\n");
SendString(sock,"User-Agent: Neeao/4.0\r\n");
strcat(headerSend, "User-Agent: Neeao/4.0\r\n");
if(postLength)
{
sprintf(buffer,"Content-Length: %ld\r\n",postLength);
SendString(sock,buffer);
strcat(headerSend, buffer);
}
//SendString(sock,"Cookie: mycookie=blablabla\r\n");
// printf("Cookie: mycookie=blablabla\r\n");
SendString(sock,"Host: ");
strcat(headerSend, "Host: ");
SendString(sock,host);
strcat(headerSend, host);
SendString(sock,"\r\n");
strcat(headerSend, "\r\n");
if( (headerReceive!=NULL) && *headerReceive )
{
SendString(sock,headerReceive);
strcat(headerSend, headerReceive);
}
SendString(sock,"\r\n"); // Send a blank line to signal end of HTTP headerReceive
strcat(headerSend, "\r\n");
if( (post!=NULL) && postLength )
{
send(sock,(const char*)post,postLength,0);
post[postLength] = '\0';
strcat(headerSend, (const char*)post);
}
//strcpy(req->headerSend, headerSend);
req->headerSend = (char*) malloc( sizeof(char*) * strlen(headerSend));
strcpy(req->headerSend, (char*) headerSend );
MemBufferCreate(&headersBuffer );
chars = 0;
done = FALSE;
while(!done)
{
l = recv(sock,buffer,1,0);
if(l<0)
done=TRUE;
switch(*buffer)
{
case '\r':
break;
case '\n':
if(chars==0)
done = TRUE;
chars=0;
break;
default:
chars++;
break;
}
MemBufferAddByte(&headersBuffer,*buffer);
}
req->headerReceive = (char*) headersBuffer.buffer;
*(headersBuffer.position) = 0;
MemBufferCreate(&messageBuffer); // Now read the HTTP body
do
{
l = recv(sock,buffer,sizeof(buffer)-1,0);
if(l<0)
break;
*(buffer+l)=0;
MemBufferAddBuffer(&messageBuffer, (unsigned char*)&buffer, l);
} while(l>0);
*messageBuffer.position = 0;
req->message = (char*) messageBuffer.buffer;
req->messageLength = (messageBuffer.position - messageBuffer.buffer);
closesocket(sock); // Cleanup
return 0;
}
//*******************************************************************************************************
// SendRequest
//
//*******************************************************************************************************
int Request::SendRequest(bool IsPost, string url, string& psHeaderSend, string& psHeaderReceive, string& psMessage)
{
HTTPRequest req;
int i,rtn;
LPSTR buffer;
req.headerSend = NULL;
req.headerReceive = NULL;
req.message = NULL;
//Read in arguments
if(IsPost)
{ /* POST */
i = psHeaderSend.length();
buffer = (char*) malloc(i+1);
strcpy(buffer, psHeaderSend.c_str());
rtn = SendHTTP( url,
"Content-Type: application/x-www-form-urlencoded\r\n",
(unsigned char*)buffer,
i,
&req);
free(buffer);
}
else/* GET */
{
rtn = SendHTTP(url,NULL,NULL,0,&req);
}
if(!rtn) //Output message and/or headerSend
{
psHeaderSend = req.headerSend;
psHeaderReceive = req.headerReceive;
psMessage = req.message;
free(req.headerSend);
free(req.headerReceive);
free(req.message);
return 1;
}
else
{
return 0;
}
}