标签归档:socket

纯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.     Request myRequest;      //初始化类 
  10.     string sHeaderSend;     //定义http头 
  11.     string sHeaderReceive;  //返回头 
  12.     string sMessage="";     //返回页面内容 
  13.     bool IsPost=false;  //是否Post提交
  14.  
  15.     int i =myRequest.SendRequest(IsPost, "http://neeao.com", sHeaderSend, 
  16. sHeaderReceive, sMessage); 
  17.     if (i) 
  18.     {    
  19.         cout<<"Http头:"<<endl; 
  20.         cout<< sHeaderSend <<endl; 
  21.         cout<<"响应头"<<endl; 
  22.         cout<< sHeaderReceive <<endl; 
  23.         cout<<"网页内容"<<endl; 
  24.         cout<< sMessage <<endl; 
  25.     }else 
  26.     { 
  27.         cout<<"网络不可到达"<<endl; 
  28.     } 
  29.     system("pause"); 
  30.     return 0; 

直接上代码了,blog附件上传貌似有点问题,

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_)  

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