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句柄。
- /***********************定义HTTP发送所用方法***********************************/
- HINTERNET OpenSession(LPCWSTR userAgent = 0)
- {
- #ifdef USE_WINHTTP
- return WinHttpOpen(userAgent, NULL, NULL, NULL, NULL);;
- #else
- return InternetOpen(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
- #endif
- }
- HINTERNET Connect(HINTERNET hSession, LPCWSTR serverAddr, int portNo)
- {
- #ifdef USE_WINHTTP
- return WinHttpConnect(hSession, serverAddr, (INTERNET_PORT) portNo, 0);
- #else
- return InternetConnect(hSession, serverAddr, portNo, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
- #endif
- }
- HINTERNET OpenRequest(HINTERNET hConnect, LPCWSTR verb,LPCWSTR objectName, int scheme)
- {
- DWORD flags = 0;
- #ifdef USE_WINHTTP
- if (scheme == INTERNET_SCHEME_HTTPS) {
- flags |= WINHTTP_FLAG_SECURE;
- }
- return WinHttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags);
- #else
- if (scheme == INTERNET_SCHEME_HTTPS) {
- flags |= INTERNET_FLAG_SECURE;
- }
- return HttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags, 0);
- #endif
- }
- BOOL AddRequestHeaders(HINTERNET hRequest,LPCWSTR header)
- {
- SIZE_T len = lstrlenW(header);
- #ifdef USE_WINHTTP
- return WinHttpAddRequestHeaders(hRequest, header,DWORD(len), WINHTTP_ADDREQ_FLAG_ADD);
- #else
- return HttpAddRequestHeaders(hRequest, header,DWORD(len), HTTP_ADDREQ_FLAG_ADD);
- #endif
- }
- BOOL SendRequest(HINTERNET hRequest,const void* body,DWORD size)
- {
- #ifdef USE_WINHTTP
- return WinHttpSendRequest(hRequest, 0, 0,const_cast<void*>(body), size, size, 0);
- #else
- return HttpSendRequest(hRequest, 0, 0,const_cast<void*>(body), size);
- #endif
- }
- BOOL EndRequest(HINTERNET hRequest)
- {
- #ifdef USE_WINHTTP
- return WinHttpReceiveResponse(hRequest, 0);
- #else
- // if you use HttpSendRequestEx to send request then use HttpEndRequest in here!
- return TRUE;
- #endif
- }
- BOOL QueryInfo(HINTERNET hRequest,int queryId, char* szBuf,DWORD* pdwSize)
- {
- #ifdef USE_WINHTTP
- return WinHttpQueryHeaders(hRequest, (DWORD) queryId, 0, szBuf, pdwSize, 0);
- #else
- return HttpQueryInfo(hRequest, queryId, szBuf, pdwSize, 0);
- #endif
- }
- BOOL ReadData(HINTERNET hRequest,void* buffer, DWORD length,DWORD* cbRead)
- {
- #ifdef USE_WINHTTP
- return WinHttpReadData(hRequest, buffer, length, cbRead);
- #else
- return InternetReadFile(hRequest, buffer, length, cbRead);
- #endif
- }
- void CloseInternetHandle(HINTERNET hInternet)
- {
- if (hInternet)
- {
- #ifdef USE_WINHTTP
- WinHttpCloseHandle(hInternet);
- #else
- InternetCloseHandle(hInternet);
- #endif
- }
- }
- /**********************************************************/
- ///通过Http方式发送短信
- string SendSMS_HTTP(const long ececcid,const string & password ,const string & msisdn,const string &smsContent)
- {
- string rtnStr ="-1";
- HINTERNET hSession = 0;
- HINTERNET hConnect = 0;
- HINTERNET hRequest = 0;
- wstring strHeader(L"Content-type: application/x-www-form-urlencoded\r\n");
- // Test data
- CrackedUrl crackedUrl(L"http://pi.f3.cn/SendSMS.aspx");
- string StrPostData = "ececcid=600000&password="+password+"&msisdn="+msisdn+"&smscontent="+smsContent+"&msgtype=5&longcode=";
- StrPostData = string_To_UTF8(StrPostData);
- // Open session.
- hSession = OpenSession(L"HttpPost by lyz_sea@163.com");
- if (hSession == NULL) {
- cout<<"Error:Open session!\n";
- return "-1";
- }
- // Connect.
- hConnect = Connect(hSession, crackedUrl.GetHostName(), crackedUrl.GetPort());
- if (hConnect == NULL) {
- cout<<"Error:Connect failed!\n";
- return "-1";
- }
- // Open request.
- hRequest = OpenRequest(hConnect, L"POST", crackedUrl.GetPath(), crackedUrl.GetScheme());
- if (hRequest == NULL) {
- cout<<"Error:OpenRequest failed!\n";
- return "-1";
- }
- // Add request header.
- if (!AddRequestHeaders(hRequest, strHeader.c_str())) {
- cout<<"Error:AddRequestHeaders failed!\n";
- return "-1";
- }
- // Send post data.
- if (!SendRequest(hRequest, StrPostData.c_str(), StrPostData.length())) {
- cout<<"Error:SendRequest failed!\n";
- return "-1";
- }
- // End request
- if (!EndRequest(hRequest)) {
- cout<<"Error:EndRequest failed!\n";
- return "-1";
- }
- char szBuf[BUF_SIZE];
- DWORD dwSize = 0;
- szBuf[0] = 0;
- // Query header info.
- #ifdef USE_WINHTTP
- int contextLengthId = WINHTTP_QUERY_CONTENT_LENGTH;
- int statusCodeId = WINHTTP_QUERY_STATUS_CODE;
- int statusTextId = WINHTTP_QUERY_STATUS_TEXT;
- #else
- int contextLengthId = HTTP_QUERY_CONTENT_LENGTH;
- int statusCodeId = HTTP_QUERY_STATUS_CODE;
- int statusTextId = HTTP_QUERY_STATUS_TEXT;
- #endif
- dwSize = BUF_SIZE;
- if (QueryInfo(hRequest, contextLengthId, szBuf, &dwSize)) {
- szBuf[dwSize] = 0;
- cout<<"Content length: "<<szBuf<<endl;
- }
- dwSize = BUF_SIZE;
- if (QueryInfo(hRequest, statusCodeId, szBuf, &dwSize)) {
- szBuf[dwSize] = 0;
- cout<<"Status code: "<< szBuf<<endl;
- }
- dwSize = BUF_SIZE;
- if (QueryInfo(hRequest, statusTextId, szBuf, &dwSize)) {
- szBuf[dwSize] = 0;
- cout<<"Status text:"<<szBuf<<endl;
- }
- // read data.
- for (;;) {
- dwSize = BUF_SIZE;
- if (ReadData(hRequest, szBuf, dwSize, &dwSize) == FALSE) {
- break;
- }
- if (dwSize <= 0) {
- break;
- }
- szBuf[dwSize] = 0;
- rtnStr =::UTF8_To_string(string(szBuf));
- cout<<rtnStr<<endl;//Output 返回值
- }
- CloseInternetHandle(hRequest);
- CloseInternetHandle(hConnect);
- CloseInternetHandle(hSession);
- return rtnStr;
- }
- 以上方法中用到的CrackURL方法在以下CrackURL.h文件中:
- #pragma once
- //#include<iostream>
- //using namespace std;
- #define USE_WINHTTP //Comment this line to user wininet.
- #ifdef USE_WINHTTP
- #include <winhttp.h>
- #pragma comment(lib, "winhttp.lib")
- #else
- #include <wininet.h>
- #pragma comment(lib, "wininet.lib")
- #endif
- // CrackedUrl
- class CrackedUrl {
- int m_scheme;
- wstring m_host;
- int m_port;
- wstring m_path;
- public:
- CrackedUrl(LPCWSTR url)
- {
- URL_COMPONENTS uc = { 0};
- uc.dwStructSize = sizeof(uc);
- const DWORD BUF_LEN = 256;
- WCHAR host[BUF_LEN];
- uc.lpszHostName = host;
- uc.dwHostNameLength = BUF_LEN;
- WCHAR path[BUF_LEN];
- uc.lpszUrlPath = path;
- uc.dwUrlPathLength = BUF_LEN;
- WCHAR extra[BUF_LEN];
- uc.lpszExtraInfo = extra;
- uc.dwExtraInfoLength = BUF_LEN;
- #ifdef USE_WINHTTP
- if (!WinHttpCrackUrl(url, 0, ICU_ESCAPE, &uc)) {
- cout<<"Error:WinHttpCrackUrl failed!\n";
- }
- #else
- if (!InternetCrackUrl(url, 0, ICU_ESCAPE, &uc)) {
- printf("Error:InternetCrackUrl failed!\n");
- }
- #endif
- m_scheme = uc.nScheme;
- m_host = host;
- m_port = uc.nPort;
- m_path = path;
- }
- int GetScheme() const
- {
- return m_scheme;
- }
- LPCWSTR GetHostName()const
- {
- return m_host.c_str();
- }
- int GetPort() const
- {
- return m_port;
- }
- LPCWSTR GetPath()const
- {
- return m_path.c_str();
- }
- static string UrlEncode(constchar* p)
- {
- if (p == 0) {
- return string();
- }
- string buf;
- for (;;) {
- int ch = (BYTE) (*(p++));
- if (ch == '\0') {
- break;
- }
- if (isalnum(ch) || ch =='_' || ch == '-' || ch =='.') {
- buf += (char)ch;
- }
- else if (ch == ' ') {
- buf += '+';
- }
- else {
- char c[16];
- wsprintfA(c, "%%%02X", ch);
- buf += c;
- }
- }
- return buf;
- }
- };
0 0
- C++调用HTTP实现方式
- C++调用HTTP实现方式
- C++调用HTTP实现方式
- C++调用HTTP实现方式
- 转 C++调用HTTP实现方式
- 淘宝http调用方式
- http方式调用webservice
- Spring MVC 用HttpInvoker实现HTTP方式远程调用
- JAVA 调用HTTP接口POST或GET实现方式
- JAVA 调用HTTP接口POST或GET实现方式
- HTTP get方式调用接口
- GO程序调用C及C++库的实现方式
- c 函数调用方式
- C语言调用方式
- C语言调用http接口
- c实现HTTP 隧道
- HTTP实现断点续传的方式
- Java实现HTTP POST方式
- 初学者dos界面编译运行Java程序
- JOptionPane类提示框的一些常用的方法
- bestCoder 2015 百度之星程序设计大赛 资格赛 1006单调区间
- 478A - Initial Bet
- 态度
- C++调用HTTP实现方式
- 欢迎使用CSDN-markdown编辑器
- Hibernate关联映射之多对一、一对一映射
- socket实现大型文件传输
- matlab报错”xlswrite函数的Object returned error code: 0x800A03EC
- log4j 加载顺序
- java获取服务器一些信息的方法
- 关于mysql 的for update
- Elasticsearch 初探及window下集群的搭建