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

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

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

2.以下是调用方法:

  1. #include "stdafx.h"   
  2. #include    
  3. #include    
  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头:"<
  21.         cout<< sHeaderSend <
  22.         cout<<"响应头"<
  23.         cout<< sHeaderReceive <
  24.         cout<<"网页内容"<
  25.         cout<< sMessage <
  26.     }else   
  27.     {   
  28.         cout<<"网络不可到达"<
  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     
  16. #include     
  17. #include     
  18. #include     
  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     
  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. }   

你可能感兴趣的:(VC/C++)