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


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

    1.项目中要使用c++++来访问Web服务器,从网上找了个C++的封装类,其中调用了MFC,在VC2005上用能用,但是移植到VC2003就出问题了,干脆修改成了纯C++的,不敢独享,share之。

    2.以下是调用方法:

     1 #include "stdafx.h" 
     2 #include <iostream> 
     3 #include <string> 
     4 #include "http\request.h" 
     5  
     6 using namespace std; 
     7  
     8 int _tmain(int argc, _TCHAR* argv[]) 
     9 
    10     Request myRequest;      //初始化类 
    11     string sHeaderSend;     //定义http头 
    12     string sHeaderReceive;  //返回头 
    13     string sMessage="";     //返回页面内容 
    14     bool IsPost=false;  //是否Post提交 
    15  
    16     int i =myRequest.SendRequest(IsPost, "http://neeao.com", sHeaderSend, 
    17                                  sHeaderReceive, sMessage); 
    18     if (i) 
    19     {    
    20         cout<<"Http头:"<<endl; 
    21         cout<< sHeaderSend <<endl; 
    22         cout<<"响应头"<<endl; 
    23         cout<< sHeaderReceive <<endl; 
    24         cout<<"网页内容"<<endl; 
    25         cout<< sMessage <<endl; 
    26     }else 
    27     { 
    28         cout<<"网络不可到达"<<endl; 
    29     } 
    30     system("pause"); 
    31     return 0
    32 
    33 

    直接上代码了,

    Request.h

     1 //******************************************  
     2 //纯C++的socket访问Http封装类,Neeao修改  
     3 //http://neeao.com  
     4 //2009-08-25  
     5 //******************************************  
     6  
     7 #if !defined(AFX_REQUEST_H__9F2C9BB6_CBA7_40AF_80A4_09A1CE1CE220__INCLUDED_)  
     8 #define AFX_REQUEST_H__9F2C9BB6_CBA7_40AF_80A4_09A1CE1CE220__INCLUDED_  
     9  
    10 #if _MSC_VER > 1000  
    11 #pragma once  
    12 #endif // _MSC_VER > 1000  
    13  
    14  
    15 #include <stdio.h>  
    16 #include <stdlib.h>  
    17 #include <string.h>  
    18 #include <winsock2.h>  
    19 #pragma comment(lib, "WS2_32")   
    20  
    21 using namespace std;  
    22 #define MEM_BUFFER_SIZE 10  
    23  
    24 /*   
    25     HTTPRequest: Structure that returns the HTTP headers and message  
    26                     from the request  
    27 */  
    28 typedef struct 
    29 {   
    30     LPSTR headerSend;                               // Pointer to HTTP header Send   
    31     LPSTR headerReceive;                            // Pointer to HTTP headers Receive  
    32     LPSTR message;                                  // Pointer to the HTTP message   
    33     long messageLength;                             // Length of the message   
    34 } HTTPRequest;  
    35  
    36 /*   
    37     MemBuffer:  Structure used to implement a memory buffer, which is a  
    38                 buffer of memory that will grow to hold variable sized  
    39                 parts of the HTTP message.   
    40 */ 
    41 typedef struct 
    42 {  
    43     unsigned    char *buffer;  
    44     unsigned    char *position;  
    45     size_t      size;  
    46 } MemBuffer;  
    47  
    48  
    49 class Request    
    50 {  
    51 public:  
    52     Request();  
    53     virtual ~Request();  
    54  
    55 private:  
    56     void        MemBufferCreate(MemBuffer *b);  
    57     void        MemBufferGrow(MemBuffer *b);  
    58     void        MemBufferAddByte(MemBuffer *b, unsigned char byt);  
    59     void        MemBufferAddBuffer(MemBuffer *b, unsigned char *buffer, size_t size);  
    60     DWORD       GetHostAddress(LPCSTR host);  
    61     void        SendString(SOCKET sock,LPCSTR str);  
    62     BOOL        ValidHostChar(char ch);  
    63     void        ParseURL(string url,LPSTR protocol,int lprotocol, LPSTR host,int lhost,LPSTR request,int lrequest,int *port);  
    64  
    65     int         SendHTTP(string url,LPCSTR headerReceive,BYTE *post, DWORD postLength,HTTPRequest *req);  
    66  
    67 public:  
    68     int     SendRequest(bool IsPost, string url, string& psHeaderSend, string& pszHeaderReceive,string& pszMessage);  
    69 };  
    70  
    71 #endif // !defined(AFX_REQUEST_H__9F2C9BB6_CBA7_40AF_80A4_09A1CE1CE220__INCLUDED_)  
    72 

    Request.cpp

      1 //******************************************  
      2 //纯C++的Socket访问Http封装类,Neeao修改  
      3 //http://neeao.com  
      4 //2009-08-25  
      5 //******************************************  
      6  
      7  
      8 #include "stdafx.h"  
      9 #include "Request.h"  
     10 #include <string>  
     11 #ifdef _DEBUG  
     12 #undef THIS_FILE  
     13 static char THIS_FILE[]=__FILE__;  
     14 #define new DEBUG_NEW  
     15 #endif  
     16  
     17  
     18 //////////////////////////////////////////////////////////////////////  
     19 // Construction/Destruction  
     20 //////////////////////////////////////////////////////////////////////  
     21  
     22 Request::Request()  
     23 {  
     24  
     25 }  
     26  
     27 Request::~Request()  
     28 {  
     29  
     30 }  
     31  
     32  
     33 //*******************************************************************************************************  
     34 //MemBufferCreate:   
     35 //                  Passed a MemBuffer structure, will allocate a memory buffer   
     36 //                   of MEM_BUFFER_SIZE.  This buffer can then grow as needed.  
     37 //*******************************************************************************************************  
     38 void Request::MemBufferCreate(MemBuffer *b)  
     39 {  
     40     b->size = MEM_BUFFER_SIZE;  
     41     b->buffer =(unsigned    char *) malloc( b->size );  
     42     b->position = b->buffer;  
     43 }  
     44  
     45 //*******************************************************************************************************  
     46 // MemBufferGrow:    
     47 //                  Double the size of the buffer that was passed to this function.   
     48 //*******************************************************************************************************  
     49 void Request::MemBufferGrow(MemBuffer *b)  
     50 {  
     51     size_t sz;  
     52     sz = b->position - b->buffer;  
     53     b->size = b->size *2;  
     54     b->buffer =(unsigned    char *) realloc(b->buffer,b->size);  
     55     b->position = b->buffer + sz;   // readjust current position  
     56 }  
     57  
     58 //*******************************************************************************************************  
     59 // MemBufferAddByte:   
     60 //                  Add a single byte to the memory buffer, grow if needed.  
     61 //*******************************************************************************************************  
     62 void Request::MemBufferAddByte(MemBuffer *b,unsigned char byt)  
     63 {  
     64     if( (size_t)(b->position-b->buffer) >= b->size )  
     65         MemBufferGrow(b);  
     66  
     67     *(b->position++= byt;  
     68 }  
     69  
     70 //*******************************************************************************************************  
     71 // MemBufferAddBuffer:  
     72 //                  Add a range of bytes to the memory buffer, grow if needed.  
     73 //*******************************************************************************************************  
     74 void Request::MemBufferAddBuffer(MemBuffer *b,  
     75                                  unsigned char *buffer, size_t size)  
     76 {  
     77     while( ((size_t)(b->position-b->buffer)+size) >= b->size )  
     78         MemBufferGrow(b);  
     79  
     80     memcpy(b->position,buffer,size);  
     81     b->position+=size;  
     82 }  
     83  
     84 //*******************************************************************************************************  
     85 // GetHostAddress:   
     86 //                  Resolve using DNS or similar(WINS,etc) the IP   
     87 //                   address for a domain name such as www.wdj.com.   
     88 //*******************************************************************************************************  
     89 DWORD Request::GetHostAddress(LPCSTR host)  
     90 {  
     91     struct hostent *phe;  
     92     char *p;  
     93  
     94     phe = gethostbyname( host );  
     95  
     96     if(phe==NULL)  
     97         return 0;  
     98  
     99     p = *phe->h_addr_list;  
    100     return *((DWORD*)p);  
    101 }  
    102  
    103 //*******************************************************************************************************  
    104 // SendString:   
    105 //                  Send a string(null terminated) over the specified socket.  
    106 //*******************************************************************************************************  
    107 void Request::SendString(SOCKET sock,LPCSTR str)  
    108 {  
    109     send(sock,str,strlen(str),0);  
    110 }  
    111  
    112 //*******************************************************************************************************  
    113 // ValidHostChar:   
    114 //                  Return TRUE if the specified character is valid  
    115 //                      for a host name, i.e. A-Z or 0-9 or -.:   
    116 //*******************************************************************************************************  
    117 BOOL Request::ValidHostChar(char ch)  
    118 {  
    119     return( isalpha(ch) || isdigit(ch)  
    120         || ch=='-' || ch=='.' || ch==':' );  
    121 }  
    122  
    123  
    124 //*******************************************************************************************************  
    125 // ParseURL:   
    126 //                  Used to break apart a URL such as   
    127 //                      http://www.localhost.com:80/TestPost.htm into protocol, port, host and request.  
    128 //*******************************************************************************************************  
    129 void Request::ParseURL(string url,LPSTR protocol,int lprotocol,LPSTR host,int lhost,LPSTR request,int lrequest,int *port)  
    130 {  
    131     char *work,*ptr,*ptr2;  
    132  
    133     *protocol = *host = *request = 0;  
    134     *port=80;  
    135  
    136     work = strdup(url.c_str());  
    137     strupr(work);  
    138  
    139     ptr = strchr(work,':');                         // find protocol if any  
    140     if(ptr!=NULL)  
    141     {  
    142         *(ptr++= 0;  
    143         lstrcpyn(protocol,work,lprotocol);  
    144     }  
    145     else 
    146     {  
    147         lstrcpyn(protocol,"HTTP",lprotocol);  
    148         ptr = work;  
    149     }  
    150  
    151     if( (*ptr=='/'&& (*(ptr+1)=='/') )            // skip past opening /'s   
    152         ptr+=2;  
    153  
    154     ptr2 = ptr;                                     // find host  
    155     while( ValidHostChar(*ptr2) && *ptr2 )  
    156         ptr2++;  
    157  
    158     *ptr2=0;  
    159     lstrcpyn(host,ptr,lhost);  
    160  
    161     lstrcpyn(request,url.c_str() + (ptr2-work),lrequest);   // find the request  
    162  
    163     ptr = strchr(host,':');                         // find the port number, if any  
    164     if(ptr!=NULL)  
    165     {  
    166         *ptr=0;  
    167         *port = atoi(ptr+1);  
    168     }  
    169  
    170     free(work);  
    171 }  
    172  
    173 //*******************************************************************************************************  
    174 // SendHTTP:   
    175 //                  Main entry point for this code.    
    176 //                    url           - The URL to GET/POST to/from.  
    177 //                    headerSend        - Headers to be sent to the server.  
    178 //                    post          - Data to be posted to the server, NULL if GET.  
    179 //                    postLength    - Length of data to post.  
    180 //                    req           - Contains the message and headerSend sent by the server.  
    181 //  
    182 //                    returns 1 on failure, 0 on success.  
    183 //*******************************************************************************************************  
    184 int Request::SendHTTP(string url,LPCSTR headerReceive,BYTE *post,  
    185                       DWORD postLength,HTTPRequest *req)  
    186 {  
    187     WSADATA         WsaData;  
    188     SOCKADDR_IN     sin;  
    189     SOCKET          sock;  
    190     char            buffer[512];  
    191     char            protocol[20],host[256],request[1024];  
    192     int             l,port,chars,err;  
    193     MemBuffer       headersBuffer,messageBuffer;  
    194     char            headerSend[1024];  
    195     BOOL            done;  
    196  
    197  
    198  
    199  
    200     ParseURL(url,protocol,sizeof(protocol),host,sizeof(host),       // Parse the URL  
    201         request,sizeof(request),&port);  
    202     if(strcmp(protocol,"HTTP"))  
    203         return 1;  
    204  
    205     err = WSAStartup (0x0101&WsaData);                            // Init Winsock  
    206     if(err!=0)  
    207         return 1;  
    208  
    209     sock = socket (AF_INET, SOCK_STREAM, 0);  
    210     //if (socket == INVALID_SOCKET)  
    211     if (sock == INVALID_SOCKET)  
    212     {  
    213         return 1;  
    214     }  
    215  
    216     sin.sin_family = AF_INET;                                       //Connect to web sever  
    217     sin.sin_port = htons( (unsigned short)port );  
    218     sin.sin_addr.s_addr = GetHostAddress(host);  
    219  
    220     if( connect (sock,(LPSOCKADDR)&sin, sizeof(SOCKADDR_IN) ) )  
    221     {  
    222  
    223         return 1;  
    224     }  
    225  
    226  
    227     if!*request )  
    228         lstrcpyn(request,"/",sizeof(request));  
    229  
    230     if( post == NULL )  
    231     {  
    232         SendString(sock,"GET ");  
    233         strcpy(headerSend, "GET ");  
    234     }  
    235     else   
    236     {  
    237         SendString(sock,"POST ");  
    238         strcpy(headerSend, "POST ");  
    239     }  
    240     SendString(sock,request);  
    241     strcat(headerSend, request);  
    242  
    243     SendString(sock," HTTP/1.0\r\n");  
    244     strcat(headerSend, " HTTP/1.0\r\n");  
    245  
    246     SendString(sock,"Accept: image/gif, image/x-xbitmap," 
    247         " image/jpeg, image/pjpeg, application/vnd.ms-excel," 
    248         " application/msword, application/vnd.ms-powerpoint," 
    249         " */*\r\n");  
    250     strcat(headerSend, "Accept: image/gif, image/x-xbitmap," 
    251         " image/jpeg, image/pjpeg, application/vnd.ms-excel," 
    252         " application/msword, application/vnd.ms-powerpoint," 
    253         " */*\r\n");  
    254  
    255     SendString(sock,"Accept-Language: en-us\r\n");  
    256     strcat(headerSend, "Accept-Language: en-us\r\n");  
    257  
    258     SendString(sock,"Accept-Encoding: gzip, default\r\n");  
    259     strcat(headerSend, "Accept-Encoding: gzip, default\r\n");  
    260  
    261     SendString(sock,"User-Agent: Neeao/4.0\r\n");  
    262     strcat(headerSend, "User-Agent: Neeao/4.0\r\n");  
    263  
    264     if(postLength)  
    265     {  
    266         sprintf(buffer,"Content-Length: %ld\r\n",postLength);  
    267         SendString(sock,buffer);  
    268         strcat(headerSend, buffer);  
    269     }  
    270     //SendString(sock,"Cookie: mycookie=blablabla\r\n");  
    271     //  printf("Cookie: mycookie=blablabla\r\n");  
    272     SendString(sock,"Host: ");  
    273     strcat(headerSend, "Host: ");  
    274  
    275     SendString(sock,host);  
    276     strcat(headerSend, host);  
    277  
    278     SendString(sock,"\r\n");  
    279     strcat(headerSend, "\r\n");  
    280  
    281     if( (headerReceive!=NULL) && *headerReceive )  
    282     {  
    283         SendString(sock,headerReceive);  
    284         strcat(headerSend, headerReceive);  
    285     }  
    286  
    287     SendString(sock,"\r\n");                                // Send a blank line to signal end of HTTP headerReceive  
    288     strcat(headerSend, "\r\n");  
    289  
    290     if( (post!=NULL) && postLength )  
    291     {  
    292         send(sock,(const char*)post,postLength,0);  
    293         post[postLength]    = '\0';  
    294  
    295         strcat(headerSend, (const char*)post);  
    296     }  
    297  
    298     //strcpy(req->headerSend, headerSend);  
    299     req->headerSend     = (char*) malloc( sizeof(char** strlen(headerSend));  
    300     strcpy(req->headerSend, (char*) headerSend );  
    301  
    302  
    303     MemBufferCreate(&headersBuffer );  
    304     chars = 0;  
    305     done = FALSE;  
    306  
    307     while(!done)  
    308     {  
    309         l = recv(sock,buffer,1,0);  
    310         if(l<0)  
    311             done=TRUE;  
    312  
    313         switch(*buffer)  
    314         {  
    315         case '\r':  
    316             break;  
    317         case '\n':  
    318             if(chars==0)  
    319                 done = TRUE;  
    320             chars=0;  
    321             break;  
    322         default:  
    323             chars++;  
    324             break;  
    325         }  
    326  
    327         MemBufferAddByte(&headersBuffer,*buffer);  
    328     }  
    329  
    330     req->headerReceive  = (char*) headersBuffer.buffer;  
    331     *(headersBuffer.position) = 0;  
    332  
    333  
    334  
    335     MemBufferCreate(&messageBuffer);                            // Now read the HTTP body  
    336  
    337     do 
    338     {  
    339         l = recv(sock,buffer,sizeof(buffer)-1,0);  
    340         if(l<0)  
    341             break;  
    342         *(buffer+l)=0;  
    343         MemBufferAddBuffer(&messageBuffer, (unsigned char*)&buffer, l);  
    344     } while(l>0);  
    345     *messageBuffer.position = 0;  
    346     req->message = (char*) messageBuffer.buffer;  
    347     req->messageLength = (messageBuffer.position - messageBuffer.buffer);  
    348  
    349  
    350     closesocket(sock);                                          // Cleanup  
    351  
    352     return 0;  
    353 }  
    354  
    355  
    356 //*******************************************************************************************************  
    357 // SendRequest  
    358 //  
    359 //*******************************************************************************************************  
    360 int Request::SendRequest(bool IsPost, string url, string& psHeaderSend, string& psHeaderReceive, string& psMessage)  
    361 {  
    362     HTTPRequest         req;  
    363     int                 i,rtn;  
    364     LPSTR               buffer;  
    365  
    366     req.headerSend                          = NULL;  
    367     req.headerReceive                       = NULL;  
    368     req.message                             = NULL;  
    369  
    370     //Read in arguments  
    371  
    372  
    373     if(IsPost)  
    374     {                                                   /* POST */  
    375         i       = psHeaderSend.length();  
    376         buffer  = (char*) malloc(i+1);  
    377         strcpy(buffer, psHeaderSend.c_str());  
    378  
    379         rtn             = SendHTTP( url,  
    380             "Content-Type: application/x-www-form-urlencoded\r\n",  
    381             (unsigned char*)buffer,  
    382             i,  
    383             &req);  
    384  
    385         free(buffer);  
    386     }  
    387     else/* GET */ 
    388     {  
    389         rtn = SendHTTP(url,NULL,NULL,0,&req);  
    390     }  
    391  
    392  
    393  
    394     if(!rtn)                                            //Output message and/or headerSend   
    395     {  
    396         psHeaderSend        = req.headerSend;  
    397         psHeaderReceive     = req.headerReceive;  
    398         psMessage           = req.message;  
    399  
    400  
    401         free(req.headerSend);  
    402         free(req.headerReceive);  
    403         free(req.message);  
    404         return 1;  
    405     }  
    406     else 
    407     {  
    408         return 0;  
    409     }  
    410 
    411 
  • 相关阅读:
    DB2 9 基础根基(730 测验)认证指南,第 2 部门: 安适性(1)
    DB2 9 根底(730 考验)认证指南,第 3 部门: 访问 DB2 数据(7)
    IT人 软件工程师的务实职业生涯规划
    《Delphi 算法与数据结构》学习与感悟[8]: 单向链表的添加、删除与遍历
    《Delphi 算法与数据结构》简介及下载
    《Delphi 算法与数据结构》学习与感悟[1]: 通过 "顺序查找" 与 "二分查找" 说明算法的重要性
    《Delphi 算法与数据结构》学习与感悟[2]: 数据对齐
    学习 TTreeView [14] StateIndex(状态图标)、OverlayIndex(叠加图标)
    《Delphi 算法与数据结构》学习与感悟[3]: 获取一个字节中非空位的个数
    《Delphi 算法与数据结构》学习与感悟[6]: 一个简单的"单向链表"
  • 原文地址:https://www.cnblogs.com/xxaxx/p/1604445.html
Copyright © 2020-2023  润新知