首页 > C++ > 纯C++的Socket访问Http封装类

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

Oct 17th,2009 发表评论
纯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; 
  • 直接上代码了,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;  
  •     }  
  • 声明: 本文采用 BY-NC-SA 协议进行授权. 转载请注明转自: 纯C++的Socket访问Http封装类
    1. 本文目前尚无任何评论.
    1. 本文目前尚无任何 trackbacks 和 pingbacks.