纯C++的Socket访问Http封装类

纯C++的Socket访问Http封装类

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; }  

类代码如下

//****************************************** //纯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; } }  

你可能感兴趣的:(C++,socket,String,null,buffer,structure)