用WinInet開發Internet客戶端應用指南

概述

一個Internet客戶端程序的目的是經過Internet協議如:HTTP、FTP等來存取網絡數據源(服務器)的信息。客戶端程序能夠訪問服務器獲 得象天氣預報,股票價格、重要新聞數據,甚至是與服務器交換信息。Internet客戶端程序能夠經過外部網絡(Internet)或內部網絡(通常爲 Intranet)訪問服務器。編程

爲了開發Internet客戶端程序。MFC類庫提供了專門的 Win32 Internet 擴展接口,也就是WinInet。MFC將WinInet封裝在一個標準的、易於使用的類集合中。在編寫WinInet客戶端程序時,你既能夠直接調用 Win32函數,也可使用WinInet類庫。瀏覽器

Win32 Internet 擴展提供了對普通Internet協議的訪問,這些協議包括:HTTP、FTP和Gopher。Gopher已經漸漸淡出。藉助於WinInet編程接 口,開發人員沒必要去了解Winsock、TCP/IP和特定Internet協議的細節就能夠編寫出高水平的Internet客戶端程序。WinInet 爲全部幾種協議(HTTP、FTP和Gopher)提供了統一的函數集,也就是Win32 API接口。利用這些統一的函數集,大大簡化了針對HTTP、FTP等協議的編程,從而輕鬆地將Internet集成到本身的應用程序中。底層協議的轉換 (如從FTP到HTTP)只要對源代碼稍做修改就能夠完成。安全

在Visual C++工程中提供有兩種方式來使用WinInet。一種是直接調用Win32 Internet函數,另外一種是使用WinInet類庫。服務器

MFC對WinInet的封裝是經過提供三個由CStdioFile派生類實現的。這三個派生類是:CInternetFile、 CHttpFile 和 CGopherFile。因爲Gopher協議已經不多使用,因此本文將再也不對CGopherFile進行討論。對開發人員來講,無論你之前是否用過 CStdioFile,WinInet都是很好理解而且易於使用的。它使得存取Internet數據易如反掌,使得Internet數據和本地數據的處理 一致透明,數據的存儲位置已經再也不重要。網絡

MFC WinInet 類有以下優勢:session

  • 緩衝器輸入輸出
  • 數據的類型安全處理
  • 許多函數的參數都是缺省值
  • 對普通的Internet錯誤進行異常處理
  • 自動清除打開的句柄和鏈接

使用 WinInet 提供的API函數,你能夠:併發

  • 經過HTTP協議下載HTML頁,HTTP協議是專門用於在服務器和客戶瀏覽器之間傳輸HTML頁。
  • 發送FTP請求上傳或下載文件以及獲取服務器的目錄信息。經過匿名登錄下載文件即是FTP的典型應用。
  • 其它基於HTTP、FTP協議的應用。

使用 WinInet 的通常流程爲:函數

下表描述了一個Internet客戶端程序實現的通常步驟:google

實現 方法
創建一個鏈接 建立CInternetSession對象,它是WinInet Internet客戶應用的前提條件
打開一個URL 創建一個鏈接,調用CInternetSession::OpenURL
函數,返回一個只讀資源對象
讀取 URL 數據 打開一個URL,調用CInternetSession::QueryOption
查詢 Internet 選項設置 創建一個鏈接,調用CInternetFile::Read
設置一個Internet選項 創建一個鏈接,調用CInternetSession::SetOption
設置一個用狀態信息調用的函數 創建一個鏈接,調用CInternetSession::EnableStatusCallback
重寫CInternetSession::OnStatusCallback函數
關閉鏈接 用CInternetSession對象方法,清除打開的鏈接

爲了建立Internet客戶端程序,MFC提供了以下的C++類和全程函數:

C++類spa

CInternetSession (父類 CObject)
CInternetConnection (父類 CObject)
    CFtpConnection
    CGopherConnection
    CHttpConnection
CInternetFile(父類 CStdioFile)
    CGopherFile
    CHttpFile
CFileFind(父類 CObject)
    CFtpFileFind
    CGopherFileFind
CGopherLocator(父類 CObject)
CInternetException(父類 CException)

全程函數

AfxParseURL
AfxGetInternetHandleType
AfxThrowInternetException

這些類和全程函數除CFileFind在AFX.H裏聲明以外,其他都在AFXINET.H文件裏聲明。它們對HTTP、FTP和Gopher等協議進行 了高度抽象,造成了一套高級API函數。 利用這些API能夠快速直接地開發Internet應用。例如,鏈接到FTP服務器通常須要幾個步驟,並且須要作一些底層處理。但使用上述的MFC類提供 的API,只須要對CInternetSession::GetFTPConnection進行一次調用,即可以輕鬆創建鏈接。

你們知道,每個Internet應用其數據交換都是創建在Internet會話(Session)的基礎之上的,MFC是經過 CInternetSession類對象來實現Internet會話的。用這個類不只能夠建立會話,並且能夠建立幾個併發的Internet會話。

爲了與服務器進行通信,除了要建立CInternetSession對象以外,還必須建立CInternetConnection對象,針對不一樣的協議,CInternetConnection對象有三種類型:

  • CInternetSession::GetFtpConnection
  • CInternetSession::GetHttpConnection
  • CInternetSession::GetGopherConnection

這些函數調用並不會讀寫服務器上的文件。若是你想要讀寫數據,必需要打開文件才能操做。其處理流程應該是這樣的:

  • 首先建立 CInternetSession 對象實例
  • 如 果建立的Session要讀寫文件,則必須建立 CInternetFile 對象實例(或者是它的子類CHttpFile、CGopherFile 對象實例)。其實,讀取數據最容易的方式是調用 CInternetSession::OpenURL函數。 這個函數解析你提供的統一資源定位符(URL),而後打開與URL指定的服務器鏈接,同時返回一個只讀的CInternetFile對象。 CInternetSession::OpenURL不針對特定的協議類型——不論是FTP仍是HTTP均可以調用,它甚至能夠處理本地文件,此時返回的 是CStdioFile,而不是CInternetFile。  
  • 若是建立的Session不讀寫文件,而是要實現其它的任務,如刪除某個FTP目錄下的文件等,則你不須要建立CInternetFile實例。

建立CInternetFile對象的方法有兩種:

  • 若是用CInternetSession::OpenURL創建與服務器的鏈接,調用返回CStdioFile。
  • 如 果用CInternetSession::GetFtpConnection、GetGopherConnection或者 CHttpConnection::OpenRequest創建與服務器的鏈接,你必須調用相應的CFtpConnection::OpenFile、 CGopherConnection::OpenFile或者CHttpConnection::OpenRequest,返回的內容也與 CInternetFile、CGopherFile或者CHttpFile對應。

綜上所述,實現Internet客戶端應用的步驟因協議而異。要看你是建立基於OpenURL的通常Internet客戶端應用,仍是使用GetXXXConnection函數之一針對特定協議的Internet客戶端應用。

在後繼文章中咱們將進一步討論用WinInet實現Internet客戶端應用程序的具體步驟和細節。

實現步驟

你們知道,每一個Internet客戶端程序都伴隨有必定的目的行爲,如讀文件、寫文件、刪除文件等等。客戶端的程序要實現這些行爲的先決條件是創建 Internet鏈接。而後再根據不一樣的目的進行具體的操做。爲了方便起見,下面這這些張表格針對不一樣的應用行爲列出了所須要的具體操做。其中列出了通常 的Internet URL (FTP、或者 HTTP)客戶端行爲要實現某個目標所必須使用的方法。這張表格的內容來自MSDN。我對部分我認爲重要的地方作了補充。

一個典型的Internet客戶端程序的處理流程

目的 方法 結果
開始一個Internet session 建立 CInternetSession 對象 初始化WinInet,並鏈接服務器
讀取或設置 InternetQuery 選項 (如超時或重試次數) 調用 CInternetSession::SetOption 不成功返回FALSE
創建回調函數監視session狀態 調用CInternetSession::EnableStatusCallback
創建回調函數
CInternetSession::OnStatusCallback,重寫OnStatusCallback,建立本身的回調例程
Internet服務器Intranet服務器或本地文件 調用 CInternetSession::OpenURL 解析並打開到指定服務器的鏈接,返回CStdioFile(若是你傳遞的OpenURL是本地文件名)或CInternetFile對象,經過存取這個對象,得到服務器或文件的數據
讀文件 調用 CInternetFile::Read 用你提供的Buffer讀指定的字節數
異常處理 在 CInternetException 類中處理 處理全部普通的 Internet 異常類型
結束 Internet session 處理 CInternetSession對象 自動清除打開的句柄的鏈接

典型的 FTP 客戶端程序實現的通常步驟

目的 方法 結果
開始一個FTP會話,創建一個FTP鏈接 建立一個CInternetSession對象,調用CInternetSession::GetFtpConnection 初始化WinInet
並聯接服務器
鏈接到一個FTP Server 用CInternetSession::GetFtpConnection 返回一個CFtpConnection對象
CD到 FTP 服務器的一個新目錄 用CFtpConnection::SetCurrentDirectory CD到FTP服務器的一個
新目錄
Find 第一個FTP目錄中的文件 建立一個CFtpFileFind對象,調用CFtpFileFind::FindFile,OpenURL函數返回一個只讀資源對象;調用CFtpFileFind::FindFile Find第一個文件,若是文件每找到返回FALSE
枚舉全部可得到的資源,Find下一個FTP目錄中的文件 Find下一個資源,調用CFtpFileFind::FindNextFile直到返回FALSE。 Find下一個文件
若是文件沒找到返回FALSE
打開FindFile或FindNextFile找到的文件(用於讀寫) 調用CFtpConnection::OpenFile,參數爲FindFile或FindNextFile返回的文件名 ,建立並打開一個CInternetFile對象 打開FindFile或FindNextFile找到的文件(用於讀寫),返回一個CInternetFile對象
讀寫文件 以讀方式打開FTP文件,用CInternetFile::Read 使用你指定的緩衝讀
指定的字節數
寫FTP文件 以寫方式打開FTP文件,調用CInternetFile::Write,重寫CInternetSession::OnStatusCallback 使用你指定的緩衝寫
指定的字節數
改變客戶端在服務器上的目錄 調用CFtpConnection::SetCurrentDirectory 進入新的目錄
獲取客戶端在服務器上的當前目錄 調用CFtpConnection::GetCurrentDirectory 獲取目錄信息
異常處理 用CInternetException類  處理全部普通的Internet異常類型
結束FTP session 處理CInternetSession對象 自動清除打開的句柄的鏈接

一個典型的刪除文件的FTP客戶端應用要實現的通常步驟

目的 方法 結果
開始一個FTP session 建立一個CInternetSession對象 初始化WinInet
並聯接服務器
鏈接到一個FTP Server 用CInternetSession::GetFtpConnection 返回一個CFtpConnection對象
檢查FTP目錄是否正確 用CFtpConnection::GetCurrentDirectory或CFtpConnection::GetCurrentDirectoryAsURL 返回目錄名字
服務器目錄或返回目錄的URL
CD(改變目錄)到 FTP 服務器的一個新目錄 用CFtpConnection::SetCurrentDirectory CD到FTP服務器的一個
新目錄
Find 第一個FTP目錄中的文件 用CFtpFileFind::FindFile Find第一個文件,若是文件每找到返回FALSE
Find 下一個FTP目錄中的文件 用CFtpFileFind::FindNextFile Find下一個文件
若是文件沒找到返回FALSE
刪除FindFile或FindNextFile找到的文件  用CFtpConnection::Remove用FindFile或FindNextFile返回的文件名 刪除FindFile或FindNextFile
找到的文件    
異常處理 用CInternetException類  處理全部普通的Internet異常類型
結束FTP session 處理CInternetSession對象 自動清除打開的句柄的鏈接

實現一個典型的 HTTP 客戶端應用程序的通常步驟

目的 方法 結果
開始HTTP會話,創建HTTP鏈接 建立 CInternetSession對象,調用CInternetSession::GetHttpConnection
建立CHttpConnection對象
初始化WinInet並聯接服務器,返回一個CHttpConnection對象
建立一個 HTTP 請求 調用CHttpConnection::OpenRequest
建立一個CHttpFile對象;
返回一個CHttpFile對象
發送一個HTTP 請求 用CHttpFile::AddRequestHeaders 而且用CHttpFile::SendRequest Find一個文件
若是文件沒找到返回FALSE
讀文件 調用CInternetFile::Read 使用你提供的緩衝讀指定的字節
獲取HTTP請求信息 調用CHttpFile::QueryInfo 從服務器獲取HTTP請求頭信息
異常處理 利用CInternetException類 處理全部普通的Internet異常類型
結束 HTTP 會話 處理CInternetSession對象 自動清除打開的句柄的鏈接

因爲時間關係,我沒有寫本文的例子代碼。不過MSDN裏有兩個簡單的例子能夠參考,一個是FTPTREE,另外一個是TEAR。此外,也能夠用「WinInet」做爲關鍵字在google裏搜一下也能找到一些使用MFC WinInet的技術信息。

相關文章
相關標籤/搜索