zoukankan      html  css  js  c++  java
  • 纯C++的Socket访问Http封装类(转)

     

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

    类代码如下

    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  
    73.    
    74. //******************************************    
    75. //纯C++的Socket访问Http封装类,Neeao修改    
    76. //http://neeao.com    
    77. //2009-08-25    
    78. //******************************************    
    79.   
    80.   
    81. #include "stdafx.h"    
    82. #include "Request.h"    
    83. #include <string>    
    84. #ifdef _DEBUG    
    85. #undef THIS_FILE    
    86. static char THIS_FILE[]=__FILE__;    
    87. #define new DEBUG_NEW    
    88. #endif    
    89.    
    90.    
    91. //////////////////////////////////////////////////////////////////////    
    92. // Construction/Destruction    
    93. //////////////////////////////////////////////////////////////////////    
    94.    
    95. Request::Request()    
    96. {    
    97.    
    98. }    
    99.    
    100. Request::~Request()    
    101. {    
    102.    
    103. }    
    104.    
    105.    
    106. //*******************************************************************************************************    
    107. //MemBufferCreate:     
    108. //                  Passed a MemBuffer structure, will allocate a memory buffer     
    109. //                   of MEM_BUFFER_SIZE.  This buffer can then grow as needed.    
    110. //*******************************************************************************************************    
    111. void Request::MemBufferCreate(MemBuffer *b)    
    112. {    
    113.     b->size = MEM_BUFFER_SIZE;    
    114.     b->buffer =(unsigned    char *) malloc( b->size );    
    115.     b->position = b->buffer;    
    116. }    
    117.    
    118. //*******************************************************************************************************    
    119. // MemBufferGrow:      
    120. //                  Double the size of the buffer that was passed to this function.     
    121. //*******************************************************************************************************    
    122. void Request::MemBufferGrow(MemBuffer *b)    
    123. {    
    124.     size_t sz;    
    125.     sz = b->position - b->buffer;    
    126.     b->size = b->size *2;    
    127.     b->buffer =(unsigned    char *) realloc(b->buffer,b->size);    
    128.     b->position = b->buffer + sz;   // readjust current position    
    129. }    
    130.    
    131. //*******************************************************************************************************    
    132. // MemBufferAddByte:     
    133. //                  Add a single byte to the memory buffer, grow if needed.    
    134. //*******************************************************************************************************    
    135. void Request::MemBufferAddByte(MemBuffer *b,unsigned char byt)    
    136. {    
    137.     if( (size_t)(b->position-b->buffer) >= b->size )    
    138.         MemBufferGrow(b);    
    139.    
    140.     *(b->position++) = byt;    
    141. }    
    142.    
    143. //*******************************************************************************************************    
    144. // MemBufferAddBuffer:    
    145. //                  Add a range of bytes to the memory buffer, grow if needed.    
    146. //*******************************************************************************************************    
    147. void Request::MemBufferAddBuffer(MemBuffer *b,    
    148.                                  unsigned char *buffer, size_t size)    
    149. {    
    150.     while( ((size_t)(b->position-b->buffer)+size) >= b->size )    
    151.         MemBufferGrow(b);    
    152.    
    153.     memcpy(b->position,buffer,size);    
    154.     b->position+=size;    
    155. }    
    156.    
    157. //*******************************************************************************************************    
    158. // GetHostAddress:     
    159. //                  Resolve using DNS or similar(WINS,etc) the IP     
    160. //                   address for a domain name such as www.wdj.com.     
    161. //*******************************************************************************************************    
    162. DWORD Request::GetHostAddress(LPCSTR host)    
    163. {    
    164.     struct hostent *phe;    
    165.     char *p;    
    166.    
    167.     phe = gethostbyname( host );    
    168.    
    169.     if(phe==NULL)    
    170.         return 0;    
    171.    
    172.     p = *phe->h_addr_list;    
    173.     return *((DWORD*)p);    
    174. }    
    175.    
    176. //*******************************************************************************************************    
    177. // SendString:     
    178. //                  Send a string(null terminated) over the specified socket.    
    179. //*******************************************************************************************************    
    180. void Request::SendString(SOCKET sock,LPCSTR str)    
    181. {    
    182.     send(sock,str,strlen(str),0);    
    183. }    
    184.    
    185. //*******************************************************************************************************    
    186. // ValidHostChar:     
    187. //                  Return TRUE if the specified character is valid    
    188. //                      for a host name, i.e. A-Z or 0-9 or -.:     
    189. //*******************************************************************************************************    
    190. BOOL Request::ValidHostChar(char ch)    
    191. {    
    192.     return( isalpha(ch) || isdigit(ch)    
    193.         || ch=='-' || ch=='.' || ch==':' );    
    194. }    
    195.    
    196.    
    197. //*******************************************************************************************************    
    198. // ParseURL:     
    199. //                  Used to break apart a URL such as     
    200. //                      http://www.localhost.com:80/TestPost.htm into protocol, port, host and request.    
    201. //*******************************************************************************************************    
    202. void Request::ParseURL(string url,LPSTR protocol,int lprotocol,LPSTR host,int lhost,LPSTR request,int lrequest,int *port)    
    203. {    
    204.     char *work,*ptr,*ptr2;    
    205.    
    206.     *protocol = *host = *request = 0;    
    207.     *port=80;    
    208.    
    209.     work = strdup(url.c_str());    
    210.     strupr(work);    
    211.    
    212.     ptr = strchr(work,':');                         // find protocol if any    
    213.     if(ptr!=NULL)    
    214.     {    
    215.         *(ptr++) = 0;    
    216.         lstrcpyn(protocol,work,lprotocol);    
    217.     }    
    218.     else   
    219.     {    
    220.         lstrcpyn(protocol,"HTTP",lprotocol);    
    221.         ptr = work;    
    222.     }    
    223.    
    224.     if( (*ptr=='/') && (*(ptr+1)=='/') )            // skip past opening /'s     
    225.         ptr+=2;    
    226.    
    227.     ptr2 = ptr;                                     // find host    
    228.     while( ValidHostChar(*ptr2) && *ptr2 )    
    229.         ptr2++;    
    230.    
    231.     *ptr2=0;    
    232.     lstrcpyn(host,ptr,lhost);    
    233.    
    234.     lstrcpyn(request,url.c_str() + (ptr2-work),lrequest);   // find the request    
    235.    
    236.     ptr = strchr(host,':');                         // find the port number, if any    
    237.     if(ptr!=NULL)    
    238.     {    
    239.         *ptr=0;    
    240.         *port = atoi(ptr+1);    
    241.     }    
    242.    
    243.     free(work);    
    244. }    
    245.    
    246. //*******************************************************************************************************    
    247. // SendHTTP:     
    248. //                  Main entry point for this code.      
    249. //                    url           - The URL to GET/POST to/from.    
    250. //                    headerSend        - Headers to be sent to the server.    
    251. //                    post          - Data to be posted to the server, NULL if GET.    
    252. //                    postLength    - Length of data to post.    
    253. //                    req           - Contains the message and headerSend sent by the server.    
    254. //    
    255. //                    returns 1 on failure, 0 on success.    
    256. //*******************************************************************************************************    
    257. int Request::SendHTTP(string url,LPCSTR headerReceive,BYTE *post,    
    258.                       DWORD postLength,HTTPRequest *req)    
    259. {    
    260.     WSADATA         WsaData;    
    261.     SOCKADDR_IN     sin;    
    262.     SOCKET          sock;    
    263.     char            buffer[512];    
    264.     char            protocol[20],host[256],request[1024];    
    265.     int             l,port,chars,err;    
    266.     MemBuffer       headersBuffer,messageBuffer;    
    267.     char            headerSend[1024];    
    268.     BOOL            done;    
    269.    
    270.    
    271.    
    272.    
    273.     ParseURL(url,protocol,sizeof(protocol),host,sizeof(host),       // Parse the URL    
    274.         request,sizeof(request),&port);    
    275.     if(strcmp(protocol,"HTTP"))    
    276.         return 1;    
    277.    
    278.     err = WSAStartup (0x0101, &WsaData);                            // Init Winsock    
    279.     if(err!=0)    
    280.         return 1;    
    281.    
    282.     sock = socket (AF_INET, SOCK_STREAM, 0);    
    283.     //if (socket == INVALID_SOCKET)    
    284.     if (sock == INVALID_SOCKET)    
    285.     {    
    286.         return 1;    
    287.     }    
    288.    
    289.     sin.sin_family = AF_INET;                                       //Connect to web sever    
    290.     sin.sin_port = htons( (unsigned short)port );    
    291.     sin.sin_addr.s_addr = GetHostAddress(host);    
    292.    
    293.     if( connect (sock,(LPSOCKADDR)&sin, sizeof(SOCKADDR_IN) ) )    
    294.     {    
    295.    
    296.         return 1;    
    297.     }    
    298.    
    299.    
    300.     if( !*request )    
    301.         lstrcpyn(request,"/",sizeof(request));    
    302.    
    303.     if( post == NULL )    
    304.     {    
    305.         SendString(sock,"GET ");    
    306.         strcpy(headerSend, "GET ");    
    307.     }    
    308.     else     
    309.     {    
    310.         SendString(sock,"POST ");    
    311.         strcpy(headerSend, "POST ");    
    312.     }    
    313.     SendString(sock,request);    
    314.     strcat(headerSend, request);    
    315.    
    316.     SendString(sock," HTTP/1.0/r/n");    
    317.     strcat(headerSend, " HTTP/1.0/r/n");    
    318.    
    319.     SendString(sock,"Accept: image/gif, image/x-xbitmap,"   
    320.         " image/jpeg, image/pjpeg, application/vnd.ms-excel,"   
    321.         " application/msword, application/vnd.ms-powerpoint,"   
    322.         " */*/r/n");    
    323.     strcat(headerSend, "Accept: image/gif, image/x-xbitmap,"   
    324.         " image/jpeg, image/pjpeg, application/vnd.ms-excel,"   
    325.         " application/msword, application/vnd.ms-powerpoint,"   
    326.         " */*/r/n");    
    327.    
    328.     SendString(sock,"Accept-Language: en-us/r/n");    
    329.     strcat(headerSend, "Accept-Language: en-us/r/n");    
    330.    
    331.     SendString(sock,"Accept-Encoding: gzip, default/r/n");    
    332.     strcat(headerSend, "Accept-Encoding: gzip, default/r/n");    
    333.    
    334.     SendString(sock,"User-Agent: Neeao/4.0/r/n");    
    335.     strcat(headerSend, "User-Agent: Neeao/4.0/r/n");    
    336.    
    337.     if(postLength)    
    338.     {    
    339.         sprintf(buffer,"Content-Length: %ld/r/n",postLength);    
    340.         SendString(sock,buffer);    
    341.         strcat(headerSend, buffer);    
    342.     }    
    343.     //SendString(sock,"Cookie: mycookie=blablabla/r/n");    
    344.     //  printf("Cookie: mycookie=blablabla/r/n");    
    345.     SendString(sock,"Host: ");    
    346.     strcat(headerSend, "Host: ");    
    347.    
    348.     SendString(sock,host);    
    349.     strcat(headerSend, host);    
    350.    
    351.     SendString(sock,"/r/n");    
    352.     strcat(headerSend, "/r/n");    
    353.    
    354.     if( (headerReceive!=NULL) && *headerReceive )    
    355.     {    
    356.         SendString(sock,headerReceive);    
    357.         strcat(headerSend, headerReceive);    
    358.     }    
    359.    
    360.     SendString(sock,"/r/n");                                // Send a blank line to signal end of HTTP headerReceive    
    361.     strcat(headerSend, "/r/n");    
    362.    
    363.     if( (post!=NULL) && postLength )    
    364.     {    
    365.         send(sock,(const char*)post,postLength,0);    
    366.         post[postLength]    = '/0';    
    367.    
    368.         strcat(headerSend, (const char*)post);    
    369.     }    
    370.    
    371.     //strcpy(req->headerSend, headerSend);    
    372.     req->headerSend     = (char*) malloc( sizeof(char*) * strlen(headerSend));    
    373.     strcpy(req->headerSend, (char*) headerSend );    
    374.    
    375.    
    376.     MemBufferCreate(&headersBuffer );    
    377.     chars = 0;    
    378.     done = FALSE;    
    379.    
    380.     while(!done)    
    381.     {    
    382.         l = recv(sock,buffer,1,0);    
    383.         if(l<0)    
    384.             done=TRUE;    
    385.    
    386.         switch(*buffer)    
    387.         {    
    388.         case '/r':    
    389.             break;    
    390.         case '/n':    
    391.             if(chars==0)    
    392.                 done = TRUE;    
    393.             chars=0;    
    394.             break;    
    395.         default:    
    396.             chars++;    
    397.             break;    
    398.         }    
    399.    
    400.         MemBufferAddByte(&headersBuffer,*buffer);    
    401.     }    
    402.    
    403.     req->headerReceive  = (char*) headersBuffer.buffer;    
    404.     *(headersBuffer.position) = 0;    
    405.    
    406.    
    407.    
    408.     MemBufferCreate(&messageBuffer);                            // Now read the HTTP body    
    409.    
    410.     do   
    411.     {    
    412.         l = recv(sock,buffer,sizeof(buffer)-1,0);    
    413.         if(l<0)    
    414.             break;    
    415.         *(buffer+l)=0;    
    416.         MemBufferAddBuffer(&messageBuffer, (unsigned char*)&buffer, l);    
    417.     } while(l>0);    
    418.     *messageBuffer.position = 0;    
    419.     req->message = (char*) messageBuffer.buffer;    
    420.     req->messageLength = (messageBuffer.position - messageBuffer.buffer);    
    421.    
    422.    
    423.     closesocket(sock);                                          // Cleanup    
    424.    
    425.     return 0;    
    426. }    
    427.    
    428.    
    429. //*******************************************************************************************************    
    430. // SendRequest    
    431. //    
    432. //*******************************************************************************************************    
    433. int Request::SendRequest(bool IsPost, string url, string& psHeaderSend, string& psHeaderReceive, string& psMessage)    
    434. {    
    435.     HTTPRequest         req;    
    436.     int                 i,rtn;    
    437.     LPSTR               buffer;    
    438.    
    439.     req.headerSend                          = NULL;    
    440.     req.headerReceive                       = NULL;    
    441.     req.message                             = NULL;    
    442.    
    443.     //Read in arguments    
    444.    
    445.    
    446.     if(IsPost)    
    447.     {                                                   /* POST */    
    448.         i       = psHeaderSend.length();    
    449.         buffer  = (char*) malloc(i+1);    
    450.         strcpy(buffer, psHeaderSend.c_str());    
    451.    
    452.         rtn             = SendHTTP( url,    
    453.             "Content-Type: application/x-www-form-urlencoded/r/n",    
    454.             (unsigned char*)buffer,    
    455.             i,    
    456.             &req);    
    457.    
    458.         free(buffer);    
    459.     }    
    460.     else/* GET */   
    461.     {    
    462.         rtn = SendHTTP(url,NULL,NULL,0,&req);    
    463.     }    
    464.    
    465.    
    466.    
    467.     if(!rtn)                                            //Output message and/or headerSend     
    468.     {    
    469.         psHeaderSend        = req.headerSend;    
    470.         psHeaderReceive     = req.headerReceive;    
    471.         psMessage           = req.message;    
    472.    
    473.    
    474.         free(req.headerSend);    
    475.         free(req.headerReceive);    
    476.         free(req.message);    
    477.         return 1;    
    478.     }    
    479.     else   
    480.     {    
    481.         return 0;    
    482.     }    
    483. }   
     
  • 相关阅读:
    「题解」洛谷 P1169 [ZJOI2007]棋盘制作
    「题解」洛谷 P4147 玉蟾宫
    dsu on tree 学习笔记
    [USACO08FEB]Hotel G「线段树」
    城市环路「树形DP」
    Siano「线段树」
    Emiya 家今天的饭「容斥+DP」
    Matlab调用其他文件夹下的函数
    基于小波金字塔的简单图像融合算法matlab实现
    知网引文网络使用方法
  • 原文地址:https://www.cnblogs.com/UnGeek/p/2717623.html
Copyright © 2011-2022 走看看