好友
阅读权限10
听众
最后登录1970-1-1
|
Cici
发表于 2009-8-31 07:21
1.项目中要使用c++++来访问Web服务器,从网上找了个C++的封装类,其中调用了MFC,在VC2005上用能用,但是移植到VC2003就出问题了,干脆修改成了纯C++的,不敢独享,share之。
2.以下是调用方法:
#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; }
}
|
|