C++调用HTTP实现方式

来源:互联网 发布:suse linux yum配置 编辑:程序博客网 时间:2024/05/19 12:15

Http访问有两种方式,GET和POST,就编程来说GET方式相对简单点,它不用向服务器提交数据,程序中使用POST方式,
提交数据并从服务器获取返回值。

为实现Http访问,微软提供了二套API:WinINet, WinHTTP。WinHTTP比WinINet更加安全和健壮,可以这么认为WinHTTP是WinINet的升级版本。
程序中,通过一个宏的设置来决定是使用WinHttp还是WinINet。

#define USE_WINHTTP      //Comment this line to user wininet.


下面来说说实现Http访问的流程(两套API都一样的流程):

1, 首先我们打开一个Session获得一个HINTERNET session句柄;

2, 然后我们使用这个session句柄与服务器连接得到一个HINTERNET connect句柄;

3, 然后我们使用这个connect句柄来打开Http 请求得到一个HINTERNET request句柄;

4, 这时我们就可以使用这个request句柄来发送数据与读取从服务器返回的数据;

5, 最后依次关闭request,connect,session句柄。

[cpp] view plaincopyprint?
  1. /***********************定义HTTP发送所用方法***********************************/ 
  2. HINTERNET OpenSession(LPCWSTR userAgent = 0) 
  3. #ifdef USE_WINHTTP 
  4.     return WinHttpOpen(userAgent, NULL, NULL, NULL, NULL);; 
  5. #else 
  6.     return InternetOpen(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); 
  7. #endif 
  8.  
  9. HINTERNET Connect(HINTERNET hSession, LPCWSTR serverAddr, int portNo) 
  10. #ifdef USE_WINHTTP 
  11.     return WinHttpConnect(hSession, serverAddr, (INTERNET_PORT) portNo, 0); 
  12. #else 
  13.     return InternetConnect(hSession, serverAddr, portNo, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); 
  14. #endif 
  15.  
  16. HINTERNET OpenRequest(HINTERNET hConnect, LPCWSTR verb,LPCWSTR objectName, int scheme) 
  17.     DWORD flags = 0; 
  18. #ifdef USE_WINHTTP 
  19.     if (scheme == INTERNET_SCHEME_HTTPS) { 
  20.         flags |= WINHTTP_FLAG_SECURE; 
  21.     } 
  22.  
  23.     return WinHttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags); 
  24.  
  25. #else 
  26.     if (scheme == INTERNET_SCHEME_HTTPS) { 
  27.         flags |= INTERNET_FLAG_SECURE; 
  28.     } 
  29.  
  30.     return HttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags, 0); 
  31. #endif 
  32.  
  33. BOOL AddRequestHeaders(HINTERNET hRequest,LPCWSTR header) 
  34.     SIZE_T len = lstrlenW(header); 
  35. #ifdef USE_WINHTTP 
  36.     return WinHttpAddRequestHeaders(hRequest, header,DWORD(len), WINHTTP_ADDREQ_FLAG_ADD); 
  37. #else 
  38.     return HttpAddRequestHeaders(hRequest, header,DWORD(len), HTTP_ADDREQ_FLAG_ADD); 
  39. #endif 
  40.  
  41. BOOL SendRequest(HINTERNET hRequest,const void* body,DWORD size) 
  42. #ifdef USE_WINHTTP 
  43.     return WinHttpSendRequest(hRequest, 0, 0,const_cast<void*>(body), size, size, 0); 
  44. #else 
  45.     return HttpSendRequest(hRequest, 0, 0,const_cast<void*>(body), size); 
  46. #endif 
  47.  
  48. BOOL EndRequest(HINTERNET hRequest) 
  49. #ifdef USE_WINHTTP 
  50.     return WinHttpReceiveResponse(hRequest, 0); 
  51. #else 
  52.     // if you use HttpSendRequestEx to send request then use HttpEndRequest in here! 
  53.     return TRUE; 
  54. #endif 
  55.  
  56. BOOL QueryInfo(HINTERNET hRequest,int queryId, char* szBuf,DWORD* pdwSize) 
  57. #ifdef USE_WINHTTP 
  58.     return WinHttpQueryHeaders(hRequest, (DWORD) queryId, 0, szBuf, pdwSize, 0); 
  59. #else 
  60.     return HttpQueryInfo(hRequest, queryId, szBuf, pdwSize, 0); 
  61. #endif 
  62.  
  63. BOOL ReadData(HINTERNET hRequest,void* buffer, DWORD length,DWORD* cbRead) 
  64. #ifdef USE_WINHTTP 
  65.     return WinHttpReadData(hRequest, buffer, length, cbRead); 
  66. #else 
  67.     return InternetReadFile(hRequest, buffer, length, cbRead); 
  68. #endif 
  69.  
  70. void CloseInternetHandle(HINTERNET hInternet) 
  71.     if (hInternet) 
  72. #ifdef USE_WINHTTP 
  73.         WinHttpCloseHandle(hInternet); 
  74. #else 
  75.         InternetCloseHandle(hInternet); 
  76. #endif 
  77.     } 
  78.  
  79. /**********************************************************/ 
  80. ///通过Http方式发送短信 
  81. string SendSMS_HTTP(const long ececcid,const string & password ,const string & msisdn,const string &smsContent) 
  82. string rtnStr ="-1"
  83.     HINTERNET hSession = 0; 
  84.     HINTERNET hConnect = 0; 
  85.     HINTERNET hRequest = 0; 
  86.     wstring strHeader(L"Content-type: application/x-www-form-urlencoded\r\n"); 
  87.  
  88.     // Test data 
  89.     CrackedUrl crackedUrl(L"http://pi.f3.cn/SendSMS.aspx"); 
  90. string StrPostData = "ececcid=600000&password="+password+"&msisdn="+msisdn+"&smscontent="+smsContent+"&msgtype=5&longcode="
  91.   
  92. StrPostData = string_To_UTF8(StrPostData); 
  93.  
  94.     // Open session. 
  95.     hSession = OpenSession(L"HttpPost by lyz_sea@163.com"); 
  96.     if (hSession == NULL) { 
  97.         cout<<"Error:Open session!\n"
  98.         return "-1"
  99.     } 
  100.  
  101.     // Connect. 
  102.     hConnect = Connect(hSession, crackedUrl.GetHostName(), crackedUrl.GetPort()); 
  103.     if (hConnect == NULL) { 
  104.         cout<<"Error:Connect failed!\n"
  105.         return "-1"
  106.     } 
  107.  
  108.     // Open request. 
  109.     hRequest = OpenRequest(hConnect, L"POST", crackedUrl.GetPath(), crackedUrl.GetScheme()); 
  110.     if (hRequest == NULL) { 
  111.         cout<<"Error:OpenRequest failed!\n"
  112.         return "-1"
  113.    } 
  114.  
  115.     // Add request header. 
  116. if (!AddRequestHeaders(hRequest, strHeader.c_str())) { 
  117.         cout<<"Error:AddRequestHeaders failed!\n"
  118.         return "-1"
  119.     } 
  120.  
  121.     // Send post data. 
  122. if (!SendRequest(hRequest, StrPostData.c_str(), StrPostData.length())) { 
  123.         cout<<"Error:SendRequest failed!\n"
  124.         return "-1"
  125.     } 
  126.  
  127.     // End request 
  128.     if (!EndRequest(hRequest)) { 
  129.         cout<<"Error:EndRequest failed!\n"
  130.         return "-1"
  131.     } 
  132.  
  133.     char szBuf[BUF_SIZE]; 
  134.     DWORD dwSize = 0; 
  135.     szBuf[0] = 0; 
  136.  
  137.     // Query header info. 
  138. #ifdef USE_WINHTTP 
  139.     int contextLengthId = WINHTTP_QUERY_CONTENT_LENGTH; 
  140.     int statusCodeId = WINHTTP_QUERY_STATUS_CODE; 
  141.     int statusTextId = WINHTTP_QUERY_STATUS_TEXT; 
  142. #else 
  143.     int contextLengthId = HTTP_QUERY_CONTENT_LENGTH; 
  144.     int statusCodeId = HTTP_QUERY_STATUS_CODE; 
  145.     int statusTextId = HTTP_QUERY_STATUS_TEXT; 
  146. #endif 
  147.     dwSize = BUF_SIZE; 
  148.     if (QueryInfo(hRequest, contextLengthId, szBuf, &dwSize)) { 
  149.         szBuf[dwSize] = 0; 
  150.         cout<<"Content length: "<<szBuf<<endl; 
  151.     } 
  152.     dwSize = BUF_SIZE; 
  153.     if (QueryInfo(hRequest, statusCodeId, szBuf, &dwSize)) { 
  154.         szBuf[dwSize] = 0; 
  155.         cout<<"Status code: "<< szBuf<<endl; 
  156.     } 
  157.  
  158.     dwSize = BUF_SIZE; 
  159.     if (QueryInfo(hRequest, statusTextId, szBuf, &dwSize)) { 
  160.         szBuf[dwSize] = 0; 
  161.         cout<<"Status text:"<<szBuf<<endl; 
  162.     } 
  163.  
  164.     // read data. 
  165.     for (;;) { 
  166.         dwSize = BUF_SIZE; 
  167.         if (ReadData(hRequest, szBuf, dwSize, &dwSize) == FALSE) { 
  168.            break
  169.         } 
  170.  
  171.         if (dwSize <= 0) { 
  172.             break
  173.         } 
  174.  
  175.         szBuf[dwSize] = 0; 
  176.          
  177.   rtnStr =::UTF8_To_string(string(szBuf)); 
  178.  
  179.   cout<<rtnStr<<endl;//Output 返回值 
  180.     
  181.     } 
  182.  
  183.     CloseInternetHandle(hRequest); 
  184.     CloseInternetHandle(hConnect); 
  185.     CloseInternetHandle(hSession); 
  186.  
  187. return  rtnStr; 
  188.  
  189.   
  190.  
  191.   
  192.  
  193. 以上方法中用到的CrackURL方法在以下CrackURL.h文件中: 
  194.  
  195. #pragma once 
  196. //#include<iostream> 
  197. //using namespace std; 
  198.  
  199. #define USE_WINHTTP    //Comment this line to user wininet. 
  200. #ifdef USE_WINHTTP 
  201.      #include <winhttp.h> 
  202.      #pragma comment(lib, "winhttp.lib") 
  203. #else 
  204.      #include <wininet.h> 
  205.      #pragma comment(lib, "wininet.lib") 
  206. #endif 
  207.  
  208.  
  209. // CrackedUrl 
  210. class CrackedUrl { 
  211.      int m_scheme; 
  212.      wstring m_host; 
  213.      int m_port; 
  214.      wstring m_path; 
  215. public
  216.      CrackedUrl(LPCWSTR url) 
  217.      { 
  218.          URL_COMPONENTS uc = { 0}; 
  219.          uc.dwStructSize = sizeof(uc); 
  220.   
  221.          const DWORD BUF_LEN = 256; 
  222.   
  223.          WCHAR host[BUF_LEN]; 
  224.          uc.lpszHostName = host; 
  225.          uc.dwHostNameLength = BUF_LEN; 
  226.   
  227.          WCHAR path[BUF_LEN]; 
  228.          uc.lpszUrlPath = path; 
  229.          uc.dwUrlPathLength = BUF_LEN; 
  230.   
  231.          WCHAR extra[BUF_LEN]; 
  232.          uc.lpszExtraInfo = extra; 
  233.          uc.dwExtraInfoLength = BUF_LEN; 
  234.   
  235. #ifdef USE_WINHTTP 
  236.          if (!WinHttpCrackUrl(url, 0, ICU_ESCAPE, &uc)) { 
  237.              cout<<"Error:WinHttpCrackUrl failed!\n"
  238.          } 
  239.   
  240. #else 
  241.          if (!InternetCrackUrl(url, 0, ICU_ESCAPE, &uc)) { 
  242.              printf("Error:InternetCrackUrl failed!\n"); 
  243.          } 
  244. #endif 
  245.          m_scheme = uc.nScheme; 
  246.          m_host = host; 
  247.          m_port = uc.nPort; 
  248.          m_path = path; 
  249.      } 
  250.   
  251.      int GetScheme() const 
  252.      { 
  253.          return m_scheme; 
  254.      } 
  255.   
  256.      LPCWSTR GetHostName()const 
  257.      { 
  258.    return m_host.c_str(); 
  259.     } 
  260.  
  261.     int GetPort() const 
  262.      { 
  263.          return m_port; 
  264.      } 
  265.   
  266.      LPCWSTR GetPath()const 
  267.      { 
  268.    return m_path.c_str(); 
  269.      } 
  270.   
  271.      static string UrlEncode(constchar* p) 
  272.      { 
  273.          if (p == 0) { 
  274.              return string(); 
  275.          } 
  276.   
  277.          string buf; 
  278.   
  279.         for (;;) { 
  280.              int ch = (BYTE) (*(p++)); 
  281.              if (ch == '\0') { 
  282.                  break
  283.              } 
  284.   
  285.              if (isalnum(ch) || ch =='_' || ch == '-' || ch =='.') { 
  286.                  buf += (char)ch; 
  287.             } 
  288.             else if (ch == ' ') { 
  289.                 buf += '+'
  290.             } 
  291.             else
  292.                 char c[16]; 
  293.                 wsprintfA(c, "%%%02X", ch); 
  294.                 buf += c; 
  295.             } 
  296.         } 
  297.  
  298.         return buf; 
  299.     } 
  300. }; 
0 0