参考了文章:https://blog.csdn.net/breakso...https://blog.csdn.net/barry10...https://blog.csdn.net/elaine_...https://blog.csdn.net/yuanwow...https://blog.csdn.net/erdong1...以及微软的官网文档。
通过比拟WinHttp、WinINet、libcurl,我决定用看起来最专精就是给http用的WinHttp,反正需要也很简略,大略不太须要扩大。
需要:发送申请,带有几个value短的参数,和一个value长度不定的参数,并接管返回数据。
#include <string>#include <iostream>#include <windows.h>#include <winhttp.h> #include <atlstr.h>#pragma comment(lib,"winhttp.lib")#pragma comment(lib,"user32.lib")using namespace std;BOOL HttpSend(wchar_t* pwszType, wchar_t* pwszIp, WORD nServerPort, wchar_t* pwcsSourcePath, char* content, char* pszOutData)//pwszType: http verb//pwszIp: ip//pwcsSourcePath: url path//content: parameters and text{ DWORD dwSize = 0; wchar_t* lpHeadBuffer = NULL; HINTERNET hSession = NULL; HINTERNET hConnect = NULL; HINTERNET hRequest = NULL; BOOL bResults = FALSE; BOOL bUTF8Code = TRUE; //Obtain a session handle hSession = WinHttpOpen(L"User Agent", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if(!hSession) { cout << "Open failed!" << endl; return FALSE; } //Specify an HTTP server with ip and port hConnect = WinHttpConnect(hSession, pwszIp, nServerPort, 0); if(!hConnect) { cout << "Connect failed!" << endl; return FALSE; } //Create an HTTP request handle hRequest = WinHttpOpenRequest(hConnect, pwszType, pwcsSourcePath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); if(!hRequest) { cout << "Open request failed!" << endl; return FALSE; } //Add header std::wstring wstrHeader[] = { L"Content-type: application/x-www-form-urlencoded\r\n"}; WinHttpAddRequestHeaders(hRequest, wstrHeader[0].c_str(), wstrHeader[0].length(), WINHTTP_ADDREQ_FLAG_ADD); //Send a request /*USES_CONVERSION; std::string strExtInfo = CW2A(content, CP_UTF8); //get content DWORD dwTotal = strExtInfo.length();*/ DWORD dwTotal = strlen(content); //bResults = WinHttpSendRequest(hRequest, wstrHeader[0].c_str(), wstrHeader[0].length(), WINHTTP_NO_REQUEST_DATA, 0, dwTotal, 0); bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, dwTotal, 0); if(!bResults) { cout << "SendRequest failed!" << endl; return FALSE; } //Write data to the server bResults = WinHttpWriteData(hRequest, content, dwTotal, NULL); if(!bResults) { cout << "WriteData failed!" << endl; return FALSE; } //End the request, receive response from server bResults = WinHttpReceiveResponse(hRequest,NULL); //Get header info if(bResults) { bResults=WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX); //Allocate buffer by header length if( GetLastError() == ERROR_INSUFFICIENT_BUFFER) //If the function fails and ERROR_INSUFFICIENT_BUFFER is returned, lpdwBufferLength specifies the number of bytes that the application must allocate to receive the string. { lpHeadBuffer = new wchar_t[dwSize / sizeof(wchar_t)]; bResults = WinHttpQueryHeaders(hRequest,WINHTTP_QUERY_RAW_HEADERS_CRLF,WINHTTP_HEADER_NAME_BY_INDEX, lpHeadBuffer, &dwSize,WINHTTP_NO_HEADER_INDEX); } //Get Content-Type from header to specify encoding if ( NULL != wcsstr(lpHeadBuffer, L"charset=gbk") ) { bUTF8Code = FALSE; } } else { cout << "Get header failed!" << endl; } printf("Header contents: \n%S", lpHeadBuffer); delete [] lpHeadBuffer; //Get data from server LPSTR pszOutBuffer = NULL; DWORD dwDownloaded = 0; wchar_t *pwText = NULL; int nSize = 0; if (bResults) { do { //Check for available data to get data size in bytes dwSize = 0; if (!WinHttpQueryDataAvailable(hRequest, &dwSize)){ cout << "Error:WinHttpQueryDataAvailable failed:" << GetLastError() << endl; bResults = FALSE; break; } if (!dwSize) { break; //data size 0 } //Allocate buffer by data size pszOutBuffer = new char[dwSize + 1]; if (!pszOutBuffer) { cout<<"Out of memory."<<endl; bResults = FALSE; break; } ZeroMemory(pszOutBuffer, dwSize + 1); //Read data from server if (!WinHttpReadData(hRequest, pszOutBuffer, dwSize, &dwDownloaded)) { cout << "Error:WinHttpQueryDataAvailable failed:" << GetLastError() << endl; } if (!dwDownloaded) { delete [] pszOutBuffer; bResults = FALSE; break; } if ( FALSE == bUTF8Code ) { //Transcoding to UTF-8 int len = MultiByteToWideChar(CP_ACP, 0, pszOutBuffer, -1, NULL, 0); //If the function succeeds and cchWideChar is 0, the return value is the required size, in characters, for the buffer indicated by lpWideCharStr wchar_t* pwszUnicode = new wchar_t[len]; memset(pwszUnicode, 0, sizeof(wchar_t) * len); MultiByteToWideChar(CP_ACP, 0, pszOutBuffer, -1, pwszUnicode, len); //map to wide char int transLen = WideCharToMultiByte(CP_UTF8, 0, pwszUnicode, len, NULL, 0, NULL, NULL); //get length nSize += transLen; WideCharToMultiByte(CP_UTF8, 0, pwszUnicode,len, pszOutData+strlen(pszOutData), transLen, NULL, NULL); //transcoding } else { strcpy_s(pszOutData + nSize, strlen(pszOutBuffer) + 1, pszOutBuffer); //SizeInBytes should not less than src length(including '\0') nSize += strlen(pszOutBuffer) + 1; } delete [] pszOutBuffer; } while (dwSize > 0); if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); return bResults; }}为了满足UTF-8编码的要求,输入输出还要有ANSI和UTF-8格局的相互转换:
...