用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 類有如下優點:
- 緩衝器輸入輸出
- 資料的型別安全處理
- 許多函數的參數都是預設值
- 對普通的Internet錯誤進行異常處理
- 自動清除開啟的控制代碼和串連
使用 WinInet 提供的API函數,你可以:
- 通過HTTP協議下載HTML頁,HTTP協議是專門用於在伺服器和客戶瀏覽器之間傳輸HTML頁。
- 發送FTP請求上傳或下載檔案以及擷取伺服器的目錄資訊。通過匿名登陸下載檔案便是FTP的典型應用。
- 其它基於HTTP、FTP協議的應用。
使用 WinInet 的一般流程為:
圖一
下表描述了一個Internet用戶端程式實現的一般步驟:
(表一)
實現 |
方法 |
建立一個串連 |
建立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++類
CInternetSession (父類 CObject)CInternetConnection (父類 CObject)CFtpConnectionCGopherConnectionCHttpConnectionCInternetFile(父類 CStdioFile)CGopherFileCHttpFileCFileFind(父類 CObject)CFtpFileFindCGopherFileFindCGopherLocator(父類 CObject)CInternetException(父類 CException)
全程函數:
AfxParseURLAfxGetInternetHandleTypeAfxThrowInternetException
這些類和全程函數除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用戶端應用。