• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            羅朝輝(飄飄白云)

            關注嵌入式操作系統(tǒng),移動平臺,圖形開發(fā)。-->加微博 ^_^

              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              85 隨筆 :: 0 文章 :: 169 評論 :: 0 Trackbacks
             

            使用WinINetWinHTTP實現(xiàn)Http訪問

            飄飄白云 l_zhaohui@163.com 2007-11-30

             

            Http訪問有兩種方式,GETPOST,就編程來說GET方式相對簡單點,它不用向服務器提交數(shù)據(jù),在這個例程中我使用POST方式,提交數(shù)據(jù)value1value2,并從服務器得到他們的和(value1 + value2)。

            為實現(xiàn)Http訪問,微軟提供了二APIWinINet, WinHTTPWinHTTPWinINet更加安全和健壯可以這么認為WinHTTPWinINet的升級版本這兩套API包含了很多相似的函數(shù)與宏定義,呵呵,詳細對比請查閱msdn中的文章“Porting WinINet Applications to WinHTTP”,在線MSDN連接:http://msdn2.microsoft.com/en-us/library/aa384068.aspx。在這個例程中,通過一個宏的設置來決定是使用WinHttp還是WinINet。代碼如下:

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

            下面來說說實現(xiàn)Http訪問的流程(兩套API都一樣的流程):

            1, 首先我們打開一個Session獲得一個HINTERNET session句柄;

            2, 然后我們使用這個session句柄與服務器連接得到一個HINTERNET connect句柄;

            3, 然后我們使用這個connect句柄來打開Http 請求得到一個HINTERNET request句柄;

            4, 這時我們就可以使用這個request句柄來發(fā)送數(shù)據(jù)與讀取從服務器返回的數(shù)據(jù);

            5, 最后依次關閉requestconnectsession句柄。

             

            在這個例程中以上各個流程都進行了簡單封裝,以便對比兩套API函數(shù)的些許差異。下面讓源代碼說話,原工程是一個windows控制臺工程,你可以很容易通過拷貝代碼重建工程。

             

            另:如果你從服務器得到的返回數(shù)據(jù)是utf8格式的文本數(shù)據(jù),你將需要對返回的數(shù)據(jù)進行轉(zhuǎn)換才能正確顯示中文,日文等。僅供參考,轉(zhuǎn)換為ATL CStringW的函數(shù)見下:

            CStringW GetStringWFromUtf8(const std::string& str)
            {
                
            int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), int(str.length()), 00);

                CStringW buf;
                WCHAR
            *    dd = buf.GetBuffer(len);

                len 
            = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), int(str.length()), dd, len);

                buf.ReleaseBuffer(len);

                
            return buf;
            }

            完整代碼如下:
              1// HttpPost.cpp written by l_zhaohui@163.com
              2// 2007/11/30
              3#include "stdafx.h"
              4#include <windows.h>
              5#include <stdio.h>
              6#include <stdlib.h>
              7
              8#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
              9#include <atlbase.h>
             10#include <atlstr.h>
             11
             12#define USE_WINHTTP    //Comment this line to user wininet.
             13#ifdef USE_WINHTTP
             14    #include <winhttp.h>
             15    #pragma comment(lib, "winhttp.lib")
             16#else
             17    #include <wininet.h>
             18    #pragma comment(lib, "wininet.lib")
             19#endif
             20#define BUF_SIZE    (1024)
             21
             22// CrackedUrl
             23class CrackedUrl {
             24    int m_scheme;
             25    CStringW m_host;
             26    int m_port;
             27    CStringW m_path;
             28public:
             29    CrackedUrl(LPCWSTR url)
             30    {
             31        URL_COMPONENTS uc = 0};
             32        uc.dwStructSize = sizeof(uc);
             33
             34        const DWORD BUF_LEN = 256;
             35
             36        WCHAR host[BUF_LEN];
             37        uc.lpszHostName = host;
             38        uc.dwHostNameLength = BUF_LEN;
             39
             40        WCHAR path[BUF_LEN];
             41        uc.lpszUrlPath = path;
             42        uc.dwUrlPathLength = BUF_LEN;
             43
             44        WCHAR extra[BUF_LEN];
             45        uc.lpszExtraInfo = extra;
             46        uc.dwExtraInfoLength = BUF_LEN;
             47
             48#ifdef USE_WINHTTP
             49        if (!WinHttpCrackUrl(url, 0, ICU_ESCAPE, &uc)) {
             50            printf("Error:WinHttpCrackUrl failed!\n");
             51        }

             52
             53#else
             54        if (!InternetCrackUrl(url, 0, ICU_ESCAPE, &uc)) {
             55            printf("Error:InternetCrackUrl failed!\n");
             56        }

             57#endif
             58        m_scheme = uc.nScheme;
             59        m_host = host;
             60        m_port = uc.nPort;
             61        m_path = path;
             62    }

             63
             64    int GetScheme() const
             65    {
             66        return m_scheme;
             67    }

             68
             69    LPCWSTR GetHostName() const
             70    {
             71        return m_host;
             72    }

             73
             74    int GetPort() const
             75    {
             76        return m_port;
             77    }

             78
             79    LPCWSTR GetPath() const
             80    {
             81        return m_path;
             82    }

             83
             84    static CStringA UrlEncode(const char* p)
             85    {
             86        if (p == 0{
             87            return CStringA();
             88        }

             89
             90        CStringA buf;
             91
             92        for (;;) {
             93            int ch = (BYTE) (*(p++));
             94            if (ch == '\0'{
             95                break;
             96            }

             97
             98            if (isalnum(ch) || ch == '_' || ch == '-' || ch == '.'{
             99                buf += (char)ch;
            100            }

            101            else if (ch == ' '{
            102                buf += '+';
            103            }

            104            else {
            105                char c[16];
            106                wsprintfA(c, "%%%02X", ch);
            107                buf += c;
            108            }

            109        }

            110
            111        return buf;
            112    }

            113}
            ;
            114
            115// CrackedUrl
            116HINTERNET OpenSession(LPCWSTR userAgent = 0)
            117{
            118#ifdef USE_WINHTTP
            119    return WinHttpOpen(userAgent, NULL, NULL, NULL, NULL);;
            120#else
            121    return InternetOpen(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
            122#endif
            123}

            124
            125HINTERNET Connect(HINTERNET hSession, LPCWSTR serverAddr, int portNo)
            126{
            127#ifdef USE_WINHTTP
            128    return WinHttpConnect(hSession, serverAddr, (INTERNET_PORT) portNo, 0);
            129#else
            130    return InternetConnect(hSession, serverAddr, portNo, NULL, NULL, INTERNET_SERVICE_HTTP, 00);
            131#endif
            132}

            133
            134HINTERNET OpenRequest(HINTERNET hConnect, LPCWSTR verb, LPCWSTR objectName, int scheme)
            135{
            136    DWORD flags = 0;
            137#ifdef USE_WINHTTP
            138    if (scheme == INTERNET_SCHEME_HTTPS) {
            139        flags |= WINHTTP_FLAG_SECURE;
            140    }

            141
            142    return WinHttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags);
            143
            144#else
            145    if (scheme == INTERNET_SCHEME_HTTPS) {
            146        flags |= INTERNET_FLAG_SECURE;
            147    }

            148
            149    return HttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags, 0);
            150#endif
            151}

            152
            153BOOL AddRequestHeaders(HINTERNET hRequest, LPCWSTR header)
            154{
            155    SIZE_T len = lstrlenW(header);
            156#ifdef USE_WINHTTP
            157    return WinHttpAddRequestHeaders(hRequest, header, DWORD(len), WINHTTP_ADDREQ_FLAG_ADD);
            158#else
            159    return HttpAddRequestHeaders(hRequest, header, DWORD(len), HTTP_ADDREQ_FLAG_ADD);
            160#endif
            161}

            162
            163BOOL SendRequest(HINTERNET hRequest, const void* body, DWORD size)
            164{
            165#ifdef USE_WINHTTP
            166    return WinHttpSendRequest(hRequest, 00, const_cast<void*>(body), size, size, 0);
            167#else
            168    return HttpSendRequest(hRequest, 00, const_cast<void*>(body), size);
            169#endif
            170}

            171
            172BOOL EndRequest(HINTERNET hRequest)
            173{
            174#ifdef USE_WINHTTP
            175    return WinHttpReceiveResponse(hRequest, 0);
            176#else
            177    // if you use HttpSendRequestEx to send request then use HttpEndRequest in here!
            178    return TRUE;
            179#endif
            180}

            181
            182BOOL QueryInfo(HINTERNET hRequest, int queryId, char* szBuf, DWORD* pdwSize)
            183{
            184#ifdef USE_WINHTTP
            185    return WinHttpQueryHeaders(hRequest, (DWORD) queryId, 0, szBuf, pdwSize, 0);
            186#else
            187    return HttpQueryInfo(hRequest, queryId, szBuf, pdwSize, 0);
            188#endif
            189}

            190
            191BOOL ReadData(HINTERNET hRequest, void* buffer, DWORD length, DWORD* cbRead)
            192{
            193#ifdef USE_WINHTTP
            194    return WinHttpReadData(hRequest, buffer, length, cbRead);
            195#else
            196    return InternetReadFile(hRequest, buffer, length, cbRead);
            197#endif
            198}

            199
            200void CloseInternetHandle(HINTERNET hInternet)
            201{
            202    if (hInternet)
            203    {
            204#ifdef USE_WINHTTP
            205        WinHttpCloseHandle(hInternet);
            206#else
            207        InternetCloseHandle(hInternet);
            208#endif
            209    }

            210}

            211
            212int _tmain(int argc, _TCHAR* argv[])
            213{
            214    HINTERNET hSession = 0;
            215    HINTERNET hConnect = 0;
            216    HINTERNET hRequest = 0;
            217    CStringW strHeader(L"Content-type: application/x-www-form-urlencoded\r\n");
            218
            219    // Test data
            220    CrackedUrl crackedUrl(L"http://www.easy-creator.net/test2/add.asp");
            221    CStringA strPostData("value1=10&value2=14");
            222
            223    // Open session.
            224    hSession = OpenSession(L"HttpPost by l_zhaohui@163.com");
            225    if (hSession == NULL) {
            226        printf("Error:Open session!\n");
            227        return -1;
            228    }

            229
            230    // Connect.
            231    hConnect = Connect(hSession, crackedUrl.GetHostName(), crackedUrl.GetPort());
            232    if (hConnect == NULL) {
            233        printf("Error:Connect failed!\n");
            234        return -1;
            235    }

            236
            237    // Open request.
            238    hRequest = OpenRequest(hConnect, L"POST", crackedUrl.GetPath(), crackedUrl.GetScheme());
            239    if (hRequest == NULL) {
            240        printf("Error:OpenRequest failed!\n");
            241        return -1;
            242    }

            243
            244    // Add request header.
            245    if (!AddRequestHeaders(hRequest, strHeader)) {
            246        printf("Error:AddRequestHeaders failed!\n");
            247        return -1;
            248    }

            249
            250    // Send post data.
            251    if (!SendRequest(hRequest, (const char*)strPostData, strPostData.GetLength())) {
            252        printf("Error:SendRequest failed!\n");
            253        return -1;
            254    }

            255
            256    // End request
            257    if (!EndRequest(hRequest)) {
            258        printf("Error:EndRequest failed!\n");
            259        return -1;
            260    }

            261
            262    char szBuf[BUF_SIZE];
            263    DWORD dwSize = 0;
            264    szBuf[0= 0;
            265
            266    // Query header info.
            267#ifdef USE_WINHTTP
            268    int contextLengthId = WINHTTP_QUERY_CONTENT_LENGTH;
            269    int statusCodeId = WINHTTP_QUERY_STATUS_CODE;
            270    int statusTextId = WINHTTP_QUERY_STATUS_TEXT;
            271#else
            272    int contextLengthId = HTTP_QUERY_CONTENT_LENGTH;
            273    int statusCodeId = HTTP_QUERY_STATUS_CODE;
            274    int statusTextId = HTTP_QUERY_STATUS_TEXT;
            275#endif
            276    dwSize = BUF_SIZE;
            277    if (QueryInfo(hRequest, contextLengthId, szBuf, &dwSize)) {
            278        szBuf[dwSize] = 0;
            279        printf("Content length:[%s]\n", szBuf);
            280    }

            281
            282    dwSize = BUF_SIZE;
            283    if (QueryInfo(hRequest, statusCodeId, szBuf, &dwSize)) {
            284        szBuf[dwSize] = 0;
            285        printf("Status code:[%s]\n", szBuf);
            286    }

            287
            288    dwSize = BUF_SIZE;
            289    if (QueryInfo(hRequest, statusTextId, szBuf, &dwSize)) {
            290        szBuf[dwSize] = 0;
            291        printf("Status text:[%s]\n", szBuf);
            292    }

            293
            294    // read data.
            295    for (;;) {
            296        dwSize = BUF_SIZE;
            297        if (ReadData(hRequest, szBuf, dwSize, &dwSize) == FALSE) {
            298            break;
            299        }

            300
            301        if (dwSize <= 0{
            302            break;
            303        }

            304
            305        szBuf[dwSize] = 0;
            306        printf("%s\n", szBuf);    //Output value = value1 + value2
            307    }

            308
            309    CloseInternetHandle(hRequest);
            310    CloseInternetHandle(hConnect);
            311    CloseInternetHandle(hSession);
            312
            313    return 0;
            314}

            315
            posted on 2007-11-30 18:16 羅朝輝 閱讀(26483) 評論(12)  編輯 收藏 引用 所屬分類: 網(wǎng)絡相關

            評論

            # re: 使用WinINet和WinHTTP實現(xiàn)Http訪問 2007-12-01 02:00 helixapp
            不錯 主要用這個實現(xiàn)自動的代理設置很方便  回復  更多評論
              

            # re: 使用WinINet和WinHTTP實現(xiàn)Http訪問 2007-12-03 09:15 夢在天涯
            不錯,超好,超喜歡哦,!

            代表大家謝謝你哦!


            哈哈

            能不能幫大家寫一個我們這個C++blog的備份工具哦

            試過好多中,不是效果不好就是不支持C++blog!

            先謝謝哦!  回復  更多評論
              

            # re: 使用WinINet和WinHTTP實現(xiàn)Http訪問 2007-12-10 09:52 飄飄白云
            @夢在天涯

            過段時間試試看看吧,最近"趕"項目,吃不消了~  回復  更多評論
              

            # re: 使用WinINet和WinHTTP實現(xiàn)Http訪問 2007-12-10 12:47 夢在天涯
            哈哈,好的謝謝先


            http://soft.pt42.cn/


            可以看看這個家伙的,寫的是很好的,可是現(xiàn)在就不支持CPP blog啊!

              回復  更多評論
              

            # re: 使用WinINet和WinHTTP實現(xiàn)Http訪問 2008-02-25 17:54 simon
            樓主強人,請教一個問題,如果我要通過proxy來訪問一個網(wǎng)站,應該在程序里的什么地方插入怎樣的語句?例如說我要通過一個地址為222.222.2.22,端口為8080的代理,代理需要驗證,用戶名為user,密碼為pass,那應該在以上程序中什么地方加入這些信息?請樓主賜教,謝謝。  回復  更多評論
              

            # re: 使用WinINet和WinHTTP實現(xiàn)Http訪問[未登錄] 2008-04-06 10:35 sky
            樓主,Linux/Unix下怎么實現(xiàn)呀~~~  回復  更多評論
              

            # re: 使用WinINet和WinHTTP實現(xiàn)Http訪問 2008-06-04 19:22 林蔭道
            post 老是傳不對呀  回復  更多評論
              

            # re: 使用WinINet和WinHTTP實現(xiàn)Http訪問 2011-08-15 11:38 Genius
            @林蔭道
            我的也不對的,數(shù)據(jù)老是不正常!!  回復  更多評論
              

            # re: 使用WinINet和WinHTTP實現(xiàn)Http訪問 2011-08-15 22:43 羅朝輝
            @Genius

            原文中的測試地址可能已經(jīng)不能用了,你是用自己的測試網(wǎng)站么?參數(shù)傳遞正確么?有沒有 encode 參數(shù)?  回復  更多評論
              

            # re: 使用WinINet和WinHTTP實現(xiàn)Http訪問 2013-03-04 15:49 周飛
            謝謝, 可以用  回復  更多評論
              

            # re: 使用WinINet和WinHTTP實現(xiàn)Http訪問 2015-11-23 17:37 測試地址可能已經(jīng)不能用了,你
            <p>
            沒看明白fasdf大沙發(fā)撒地方阿斯蒂芬阿斯方式的飛是
            手動閥sdf速度
            阿斯蒂芬as地方sd飛asdf
            阿斯發(fā)順豐
            </p>
              回復  更多評論
              

            # re: 使用WinINet和WinHTTP實現(xiàn)Http訪問 2015-11-23 17:39 測試地址可能已經(jīng)不能用了,你
            ybrj.net  回復  更多評論
              

            精品久久久一二三区| 久久精品国产亚洲av麻豆色欲| 国产精品免费福利久久| 国产午夜精品久久久久免费视| 久久久久亚洲精品无码网址| 亚洲а∨天堂久久精品9966| 亚洲?V乱码久久精品蜜桃 | 亚洲伊人久久成综合人影院 | 久久久国产精品亚洲一区| 一本综合久久国产二区| 久久人人爽人人爽人人片AV东京热| 久久99精品国产99久久6男男| 久久精品国产亚洲一区二区三区| 久久久久久久久久久| 久久综合九色综合欧美狠狠| 要久久爱在线免费观看| 亚洲午夜无码久久久久小说| 伊人久久精品影院| 大香伊人久久精品一区二区| 国产精品久久久久免费a∨| 久久精品国产乱子伦| 无码人妻久久一区二区三区免费丨 | 久久精品国产99国产精品| 久久影院久久香蕉国产线看观看| 开心久久婷婷综合中文字幕| 久久伊人影视| 久久综合给久久狠狠97色| 国产精品欧美亚洲韩国日本久久| 久久不见久久见免费视频7| 国产精品久久99| 久久水蜜桃亚洲av无码精品麻豆| 久久国产精品成人影院| 久久精品国产免费| 久久大香萑太香蕉av| 久久99亚洲网美利坚合众国| 超级碰久久免费公开视频| 亚洲国产精品无码久久九九| 久久婷婷五月综合国产尤物app| www亚洲欲色成人久久精品| 久久久亚洲欧洲日产国码是AV| 久久精品国产精品青草|