参考了文章:
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格局的相互转换:

char* Ansi2Utf8(string content){    int nLen = MultiByteToWideChar(CP_ACP, NULL, content.c_str(), content.length(), NULL, 0);    wchar_t* wszText = new wchar_t[nLen + 1];    nLen = MultiByteToWideChar(CP_ACP, NULL, content.c_str(), content.length(), wszText, nLen);    wszText[nLen] = '\0';    nLen = WideCharToMultiByte(CP_UTF8, NULL, wszText, -1, NULL, NULL, NULL, NULL);    char* contextBuf = new char[nLen];    nLen = WideCharToMultiByte(CP_UTF8, NULL, wszText, -1, contextBuf, nLen, NULL, NULL);    contextBuf[nLen] = '\0';    return contextBuf;}char* Utf82Ansi(char* res){    int len = MultiByteToWideChar(CP_UTF8, 0, res, -1, NULL, 0);    wchar_t* wstr = new wchar_t[len + 1];    memset(wstr, 0, len + 1);    MultiByteToWideChar(CP_UTF8, 0, res, -1, wstr, len);    len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);    char* str = new char[len + 1];    memset(str, 0, len + 1);    WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);    return str;}

最初调用

    string text = "xxxx";    string content = "&key=value&..." + text;    //trans ansi text to UTF-8 //Assume that input encoding = UTF-8    char* contextBuf = Ansi2Utf8(content);        wchar_t verb[] = L"POST";    wchar_t ip[] = L"(IP地址)";    WORD port = 端口号;    wchar_t path[] = L"门路";    char res[1000];    memset(res, 0, 1000);    BOOL bRet = HttpSend(verb, ip, port, path, contextBuf, res);    if (!bRet)    {        system("pause");        return -1;    }    char* transText = Utf82Ansi(res);    cout << "Original text: " << text << endl;    cout << "Translation: " << transText << endl;    system("pause");

两头掉了有数坑,ANSI转码到UTF-8如同还不是间接的……记录一下。