<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    The NoteBook of EricKong

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks
    1.關于WinINet
    WinINet不是給服務端用的,服務端用Microsoft Windows HTTP Services (WinHTTP)
    WinINet抽象了Gopher,FTP,HTTP協議的一些細節。
    2.HINTERNET 句柄

    WinINet函數創建、使用的句柄都是HINTERNET類型的,這種類型的句柄無法被轉換成其 它類型的句柄。換句話說,最好別用ReadFile、CloseHandle之類的函數來操作這些句柄。同樣的,也別用WinINet函數來訪問、操作其 他類型的句柄。比如,用InternetReadFile訪問CreateFile創建句柄是無法得到你想要的結果的。想關閉HINTERNET句柄要使 用InternetCloseHandle函數。

    3.句柄架構



    InternetOpen 創建的句柄在頂層,由接下來的一層的 InternetOpenUrlInternetConnect 使用,而 InternetConnect 創建的句柄又被之后的幾個函數使用。

    下面這張圖是依賴 InternetOpenUrl 創建的句柄的幾個函數,灰色的方框是返回 HINTERNET 句柄的函數,而白色的框就是使用被創建的 HINTERNET 句柄的函數



    FTP Hierarchy






    HTTP Hierarchy






    注意這張圖,這張圖的意思是 HttpSendRequestEx 先訪問 HttpOpenRequest 創建的句柄之后, HttpEndRequest, InternetReadFileExInternetWriteFile 才能訪問這個句柄。 HttpEndRequest 被調用之后,才輪的到InternetReadFile, InternetSetFilePointerInternetQueryDataAvailable 來訪問這個句柄。

    4.內容編碼

    HTTP 協議 (RFC 2616) 規定了應用程序可以要求服務器用編碼的方式(encoded format)返回HTTP響應。在Windows Server 2008 與 Windows Vista之前,發送給應用程序的內容編碼了的請求需要應用程序自己處理,從Windows Server 2008 and Windows Vista開始, 應用程序可以讓 WinINet 來解碼了(gzip與deflate)。有三種方式開啟解碼選項(基于會話、請求、連接),它們的作用域不同。可以使用InternetOpen(基于會話), InternetConnect(基于連接), HttpOpenRequest(基于請求)返回的句柄調用InternetSetOption 來打開或關閉解碼選項,打開則將 dwOption 參數中INTERNET_OPTION_HTTP_DECODING 選項打開, 令 lpBuffer 指向一個為true的boolean變量. 關閉則dwOption 參數中INTERNET_OPTION_HTTP_DECODING 選項打開, 令 lpBuffer 指向一個為false的boolean變量 .

    設置解碼選項之后, WinInet 在你調用 InternetReadFile 是就會執行一次解碼。不過就算你打開了解碼選項,它也不一定就為你解碼……當這種情況發生時, InternetReadFile 函數會失敗并返回ERROR_INTERNET_DECODING_FAILED.這個時候你可以選擇去掉Accept-Encoding頭重新發送一次請求,或者把解碼關掉然后自己來解碼(這時你就得檢查Content-Encoding頭來判斷編碼方式了)。

    5.協議無關函數

    Function Description
    InternetFindNextFile 繼續文件的枚舉或搜索. 需要以下函數創建的句柄 FtpFindFirstFile, GopherFindFirstFile, InternetOpenUrl
    InternetLockRequestFile 允許用戶鎖定文件. 需要以下函數創建的句柄 FtpOpenFile, GopherOpenFile, HttpOpenRequest, InternetOpenUrl .
    InternetQueryDataAvailable 查詢可用數據的數量. 需要以下函數創建的句柄 FtpOpenFile, GopherOpenFile, HttpOpenRequest .
    InternetQueryOption 查詢 Internet 設置.
    InternetReadFile 讀取 URL 數據. 需要以下函數創建的句柄 InternetOpenUrl, FtpOpenFile, GopherOpenFile, HttpOpenRequest .
    InternetSetFilePointer 設置文件指針. 需要以下函數創建的句柄 InternetOpenUrl ( HTTP URL only) HttpOpenRequest (GET 方法).
    InternetSetOption 配置 Internet 設置.
    InternetSetStatusCallback 設置一個接收狀態信息的回調函數. 分配一個回調函數給指定的 HINTERNET 句柄及從其演化而來的句柄.
    InternetUnlockRequestFile 解鎖被 InternetLockRequestFile 鎖定的文件.

    讀文件

    函數 InternetReadFile 用來從一個由函數 InternetOpenUrl, FtpOpenFile, GopherOpenFile, HttpOpenRequest 返回的 HINTERNET 句柄下載資源.

    WinINet 提供了兩種方法來下載整個資源

    尋找文件

    先使用 FtpFindFirstFile, GopherFindFirstFile, 或 InternetOpenUrl ,然后將其返回的句柄作為參數 傳遞給 InternetFindNextFile 進行繼續查找,持續調用 InternetFindNextFile 知道返回擴展的錯誤信息 ERROR_NO_MORE_FILES 來完成整個搜索,調用 GetLastError 來獲取最后的錯誤信息.

    6.HTTP 會話



    使用 WinINet 函數訪問WWW資源

    (1)初始化 WWW 連接

    將服務類型設為 INTERNET_SERVICE_HTTP 調用 InternetConnect 來建立一個 HTTP 會話

    HINTERNET InternetConnect(
    __in HINTERNET hInternet, //InternetOpen 返回的句柄
    __in LPCTSTR lpszServerName, //可以描述目標服務器的字符串
    __in INTERNET_PORT nServerPort,//目標服務器的端口
    __in LPCTSTR lpszUsername,//用戶名
    __in LPCTSTR lpszPassword,//密碼
    __in DWORD dwService,//使用的服務類型
    __in DWORD dwFlags,
    __in DWORD_PTR dwContext
    );
    nServerPort
    Value Meaning

    INTERNET_DEFAULT_FTP_PORT

    Uses the default port for FTP servers (port 21).

    INTERNET_DEFAULT_GOPHER_PORT

    Uses the default port for Gopher servers (port 70).

    INTERNET_DEFAULT_HTTP_PORT

    Uses the default port for HTTP servers (port 80).

    INTERNET_DEFAULT_HTTPS_PORT

    Uses the default port for Secure Hypertext Transfer Protocol (HTTPS) servers (port 443).

    INTERNET_DEFAULT_SOCKS_PORT

    Uses the default port for SOCKS firewall servers (port 1080).

    INTERNET_INVALID_PORT_NUMBER

    Uses the default port for the service specified by dwService.

    ldwService
    Value Meaning

    INTERNET_SERVICE_FTP

    FTP service.

    INTERNET_SERVICE_GOPHER

    Gopher service.

    INTERNET_SERVICE_HTTP

    HTTP service.

    (2)建立請求

    調用 HttpOpenRequest 來建立一個 HTTP 請求,不過這個函數不會自動把請求發送出去,要發送請求需要調用 HttpSendRequest

    HttpOpenRequest 原型


    HINTERNET HttpOpenRequest(
    __in HINTERNET hConnect, // InternetConnect 函數返回的句柄
    __in LPCTSTR lpszVerb, // 動作,有GET, PUT, POST。也可以設置為 NULL ,會被當成默認的 GET 來用
    __in LPCTSTR lpszObjectName, // 一個描述你請求資源的字符串,當請求一個默認頁面時令這個參數指向一個空串
    __in LPCTSTR lpszVersion, // HTTP 版本,這個參數為 NULL 時,默認使用""HTTP/1.1""
    __in LPCTSTR lpszReferer, // 說明了lpszObjectName是取自哪個文件,可以設為NULL
    __in LPCTSTR *lplpszAcceptTypes, //
    是一個指向LPCTSTR數組的指針!數組以一個NULL指針結束。指定了程序接受的內容的類型,設為空則不接受 任何類型的內容,設為空串則等價于""text/*"",即不接受文本文件以外的圖片等文件,只接受某種特定的文件可以用類似"image/gif, image/jpeg"的方式。關于更多內容類型 請看這里
    __in DWORD dwFlags, // 一般都可以設置為 0
    __in DWORD_PTR dwContext // 一般都可以設置為 0
    );

    (3)添加請求

    HttpAddRequestHeaders 原型

    BOOL HttpAddRequestHeaders(
       __in HINTERNET hConnect,//HttpOpenRequest 返回的句柄
       __in LPCTSTR lpszHeaders,//包含要添加到請求中的頭的字符串的指針,每個頭都要以一個 CR/LF ( "r"n"r"n ) 對結束
       __in DWORD dwHeadersLength,//lpszHeaders指向的字符串的長度(以TCHAR類型記). 如果這個參數被設為-1,則字符串被當作以0結尾的字符串處理,自動計算該字符串的長度
       __in DWORD dwModifiers
    );
    dwModifiers

    可以是下面這些值的組合

    Value Meaning

    HTTP_ADDREQ_FLAG_ADD

    Adds the header if it does not exist. Used with HTTP_ADDREQ_FLAG_REPLACE.

    HTTP_ADDREQ_FLAG_ADD_IF_NEW

    Adds the header only if it does not already exist; otherwise, an error is returned.

    HTTP_ADDREQ_FLAG_COALESCE

    Coalesces headers of the same name.

    HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA

    Coalesces headers of the same name. For example, adding "Accept: text/*" followed by "Accept: audio/*" with this flag results in the formation of the single header "Accept: text/*, audio/*". This causes the first header found to be coalesced. It is up to the calling application to ensure a cohesive scheme with respect to coalesced/separate headers.

    HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON

    Coalesces headers of the same name using a semicolon.

    HTTP_ADDREQ_FLAG_REPLACE

    Replaces or removes a header. If the header value is empty and the header is found, it is removed. If not empty, the header value is replaced.

    (4)發送一個請求

    HttpSendRequest

    BOOL HttpSendRequest(
    __in HINTERNET hRequest, //HttpOpenRequst 返回的句柄
    __in LPCTSTR lpszHeaders, //附加到請求上的頭,可以為NULL
    __in DWORD dwHeadersLength, //lpszHeaders指向的字符串的長度(以TCHAR類型記). 如果這個參數被設為-1,當調用的是HttpSendRequestA時則字符串被當作以0結尾的字符串處理,自動計算該字符串的長度。當調用的是 HttpSendRequestW時就會產生一個錯誤
    __in LPVOID lpOptional, //當使用POST或PUT方法時,這個參數指向的數據會緊接著請求被發送出去。沒有需要發送的數據則可以設置為NULL
    __in DWORD dwOptionalLength //lpOptional數據的字節長度,無數據時設置為0
    );

    (5)向服務器發送數據

    方法一:參見上面HttpSentRequest的lpOptional參數的說明

    方法二:使用 InternetWriteFile 向一個句柄里發送數據,然后使用 HttpSendRequestEx 發送

    (6)查詢一個請求的信息

    HttpQueryInfo

    BOOL HttpQueryInfo(
    __in      HINTERNET hRequest, /*由 HttpOpenRequest 或 InternetOpenUrl 返回的句柄*/
    __in      DWORD dwInfoLevel,/*
    Query Info Flags.*/
       __inout LPVOID lpvBuffer, /*用于存儲查詢結果的緩沖區,不可為NULL*/
    __inout LPDWORD lpdwBufferLength,/*lpvBuffer指向的緩沖區的字節長度
             若函數執行成功,這個變量存儲的是寫到緩沖區里的數據長度。如果數據是字符串則返回的長度不包括字符串的結束字符
             如果函數發生 ERROR_INSUFFICIENT_BUFFER 錯誤, 則這個變量里保存的是數據的實際字節長度程序需要根據這個長度重新分配內存,再執行一次這個函數*/
    __inout LPDWORD lpdwIndex /*沒看大明白,不過似乎可以設置為NULL
            Pointer to a zero-based header index used to enumerate multiple headers with the same name.
            When calling the function, this parameter is the index of the specified header to return.
            When the function returns, this parameter is the index of the next header.
            If the next index cannot be found, ERROR_HTTP_HEADER_NOT_FOUND is returned.*/
    );

    (7) WWW 上下載資源

    在調用 HttpOpenRequestHttpSendRequest 之后, 程序可以使用 InternetReadFile, InternetQueryDataAvailable, InternetSetFilePointer 來下載HTTP服務器上的資源了。

    BOOL InternetQueryDataAvailable(//查詢數據的長度
    __in HINTERNET hFile, //由 InternetOpenUrl, FtpOpenFile, GopherOpenFile, 或 HttpOpenRequest
    返回的句柄
    __out LPDWORD lpdwNumberOfBytesAvailable, //用于存放數據長度的指針
    __in DWORD dwFlags, //保留參數,置0
    __in DWORD_PTR dwContext //保留參數,置0
    );
    BOOL InternetReadFile( //讀取句柄的數據
    __in    HINTERNET hFile, // InternetOpenUrl, FtpOpenFile, GopherOpenFile, HttpOpenRequest 創建的句柄
    __out LPVOID lpBuffer, // 存放數據的緩沖區
    __in    DWORD dwNumberOfBytesToRead, // 準備讀取的字節數
    __out LPDWORD lpdwNumberOfBytesRead // 讀取了的字節數
    );

    DWORD InternetSetFilePointer( //設置InternetReadFile的文件位置(莫非多線程下載就是用這個實現的?),服務器不支持隨機訪問的話函數調用會失敗,如果 InternetReadFile已經讀取到了文件的末尾,這個函數的調用也會失敗。
    __in HINTERNET hFile, //由 InternetOpenUrl (on an HTTP or HTTPS URL)創建。 或由HttpOpenRequest 創建(使用 GET 或 HEAD方法,而且句柄已經被 HttpSendRequest 訪問過了).
    這個句柄也不可以使用 INTERNET_FLAG_DONT_CACHE 或 INTERNET_FLAG_NO_CACHE_WRITE 標志
    __in LONG lDistanceToMove, //移動的字節數。正數向后移動,負數向前移動
    __in PVOID pReserved, //保留參數,為NULL
    __in DWORD dwMoveMethod, //指定了移動指針時的參考點。FILE_BEGIN(使用這個標志時,移動的字節數被當作無符號數處理)、FILE_CURRENT、FILE_END(如果內容的長度無法獲得,則使用這個標志時會失敗)
    __in DWORD_PTR dwContext //保留參數,為NULL
    );
    posted on 2010-07-21 12:57 Eric_jiang 閱讀(3637) 評論(1)  編輯  收藏 所屬分類: Window編程

    Feedback

    # re: WinINet 學習資料 2010-08-13 16:08 劉季云
    真是好,謝謝樓主!  回復  更多評論
      


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 国产精品亚洲lv粉色| 亚洲一区二区三区免费视频| 久久噜噜噜久久亚洲va久| 老司机在线免费视频| sss日本免费完整版在线观看| 精品无码一区二区三区亚洲桃色| 超pen个人视频国产免费观看| A国产一区二区免费入口| 亚洲五月综合网色九月色| 亚洲?V无码乱码国产精品 | 国产97视频人人做人人爱免费| 亚洲AV无码国产精品麻豆天美 | 亚洲福利精品一区二区三区| 日韩精品在线免费观看| 亚洲国产精品成人AV在线| 久久久久久久综合日本亚洲| 啦啦啦在线免费视频| 免费网站看av片| 猫咪免费观看人成网站在线| 91亚洲导航深夜福利| 亚洲国产成人精品女人久久久| 57pao一国产成视频永久免费| 色吊丝性永久免费看码| 亚洲国产成人久久| 国产亚洲成av人片在线观看| 国产伦一区二区三区免费| 最近中文字幕免费2019| 成在线人视频免费视频 | 成人免费一区二区无码视频| 最近免费字幕中文大全| 羞羞漫画页面免费入口欢迎你| 亚洲一区中文字幕在线观看| 国产V亚洲V天堂无码| 免费永久在线观看黄网站| 中文字幕影片免费在线观看| 最近2019中文免费字幕在线观看| 美女免费视频一区二区三区| 一区二区亚洲精品精华液| 亚洲制服在线观看| 亚洲精品国产成人专区| 亚洲热妇无码AV在线播放|