翻譯:CFNetwork編程指南(一)——CFNetwork概念(CFNetwork Concepts)

CFNetwork是一個低級別高性能的框架,使你能夠精細的控制協議棧。它是BSD套接字的擴展,標準套接字抽象API提供對象來簡化任務,例如與FTP和HTTP服務器通信或解析DNS主機。CFNetwork物理上和理論上都基于BSD套接字。

正如CFNetwork依賴與BSD套接字,有大量的Cocoa類依賴CFNetwork(例如,NSURL)。此外,Cocoa類的web工具包用來在窗口顯示網頁內容。這兩個類是高層級,并實現大部分的網絡協議。因此,軟件層的結構如圖1-1所示。

圖1-1 OS X上CFNetwork和其他軟件層

何時使用CFNetwork

CFNetwork相對BSD套接字有很多優點,它提供了run-loop集成,因此,如果你的應用程序是基于運行循環,你可以使用網絡協議,而不用實現線程。CFNetwork還包含大量的對象可幫助你使用網絡協議,而不用實現具體的細節。例如,你可以使用FTP協議,而不用實現CFFTP API的所有細節。如果你了解網絡協議,需要它們提供低級別的控制,但是不想自己實現,這時CFNetwork可能是正確的選擇。

使用CFNetwork替代Foundation 級別網絡API有很多好處。CFNetwork更側重于網絡協議,而Foundation 級別API側重于數據訪問,例如通過HTTP或FTP傳輸數據。雖然框架API提供了一些可配置性,但CFNetwork提供了更多。關于框架網絡類的更多信息,請參閱URL加載系統編程指南(URL Loading System Programming Guide)。

現在你已了解CFNetwork如何與其他OS X網絡API交互,可以開始了解CFNetwork API和形成CFNetwork基礎的兩個API。

CFNetwork基礎

在學習CFNetwork API之前,你首先需要了解API,這些API是CFNetwork的基礎。CFNetwork依賴的兩個API:CFSocket和CFStream是核心基礎框架的一部分。理解這兩個API對使用CFNetwork至關重要。

CFSocket API

套接字是網絡通信的底層。一個套接字類似于電話插孔。它允許你連接到另一個套接字(通過本地或網絡)并發送數據給該套接字。

最常見的套接字是BSD套接字。CFSocket是BSD套接字的一個抽象概念。CFSocket提供幾乎BSD套接字的所有功能,使用很少的開銷將套接字集成到一個運行循環中。CFSocket并不局限于基于流套接字(例如,TCP),它可以處理任何類型的套接字。

你可以使用CFSocketCreate 函數從頭創建一個CFSocket對象,或者使用CFSocketCreateWithNative 函數創建。然后你可以使用函數CFSocketCreateRunLoopSource 創建一個運行循環源,并使用函數CFRunLoopAddSource將其添加到運行循環。這樣,當CFSocket對象接收到一條消息時,你的CFSocket回調函數會運行起來。

關于更多CFSocket API的信息,可閱讀CFSocket參考(CFSocket Reference)。

CFStream API

讀寫流提供一種簡單的方法以與設備無關的方式來與各種媒體進行數據交換。你可以為內存中、文件中或網絡中(使用套接字)的數據創建流,并且你可以使用流而無需將所有的數據加載到內存中。

流是一個字節序列串行傳輸的通信路徑。流是單向路徑,所以需要一個雙向通信,一個輸入(讀取)流和一個輸出(寫入)流。除了基于文件的流,你不能尋找一個流;一旦數據流被提供或消耗,不能從流中重新取回。

CFStream是一個API,它為兩個新CFType對象:CFReadStream 和CFWriteStream提供了一個抽象。這兩種類型的流遵守所有常見核心基礎API約定。關于核心基礎類型的更多信息,可參閱核心基礎設計概念(Core Foundation Design Concepts)。

CFStream構建在CFSocket之上,在CFHTTP和CFFTP之下。如圖1-2可以看出,盡管CFStream不是CFNetwork正式的部分,但它是幾乎所有CFNetwork的基礎。

圖1-2 CFStream API結構

你可以像使用UNIX文件描述符一樣使用讀寫流。首先,你指定流類型(內存、文件或套接字)實例化流并設置選項。接下來,你可以多次打開流并進行讀寫。流存在時,可以訪問屬性獲得流信息。流屬性是關于流的所有信息,例如它的源或目標,但不是實際寫入或讀取的數據。當你不再需要流時,關閉并處理它。

用于讀寫流的CFStream函數將暫停或阻塞當前進程,直到數據可以讀取或寫入。為了避免在流阻塞的時候試圖讀取或寫入流,使用異步函數并安排流到一個運行循環上。當可以無阻塞的讀取和寫入時,將調用你的回調函數。

此外,CFStream內置支持安全套接字層(SSL)協議。你可以設置包含流SSL信息的字典,例如屬性的安全級別或自簽證書。然后傳遞它給你的流,正如kCFStreamPropertySSLSettings 屬性設置流為SSL流。

使用流(Working with Streams)章節描述了如何使用讀寫流。

CFNetwork API 概念

為了理解CFNetwork框架,你需要熟悉構建它的block。CFNetwork框架分成單獨的API,每個API覆蓋一個特定的網絡協議。這些API可以結合使用或分開使用,這取決于你的應用。API大多數編程約定是常見的,所以理解他們很重要。

CFFTP API

使用CFFTP與FTP服務器通信會更加容易,使用CFFTP API,你可以創建FTP讀取流(下載)和FTP寫入流(上傳)。使用FTP讀寫流,你可以執行如下功能:

  • 從FTP服務器下載文件

  • 上傳文件到FTP服務器

  • 從FTP服務器下載目錄清單

  • 在FTP服務器上創建目錄。

FTP流就像其他CFNetwork流一樣工作。例如,你可以通過調用CFReadStreamCreateWithFTPURL 函數,創建一個FTP讀取流。然后,你可以在任何時候調用CFReadStreamGetError 函數來檢查流的狀態。

通過設置FTP流的屬性,你可以為特定應用調整你的流。例如,如果流連接的服務器需要一個用戶名和密碼,你需要設置特定的屬性這樣流可以正常工作。關于FTP流不同屬性的更多信息,請參閱設置流(Setting up the Streams)。

可以同步或異步使用CFFTP流。為了打開與FTP服務器的連接,調用CFReadStreamOpen函數,該服務器在FTP讀取流創建的時候就已指定。為了讀取流,使用CFReadStreamRead 函數并提供讀取流引用CFReadStreamRef,當創建FTP讀取流時該引用會返回。CFReadStreamRead 函數用FTP服務器輸出填充緩存區。

關于使用CFFTP的更多信息,參閱使用FTP服務器(Working with FTP Servers

CFHTTP API

發送和接收HTTP消息可使用CFHTTP API。正如CFFTP是FTP協議的抽象,CFHTTP是HTTP協議的抽象。

超文本傳輸協議(HTTP)是一種客戶端和服務器端的請求/響應協議。客戶端創建一個請求消息。這個消息被序列化,序列化其實就是將消息轉換成原始字節流。消息不能傳遞除非先被序列化。然后將請求消息發送到服務器。請求通常是請求一個文件,例如網頁。服務器響應并后發送回一個字符串然后是消息。這個過程可以重復多次。

要創建一個HTTP請求消息,你指定以下內容:

  • 請求方法,可以是超文本傳輸協議定義的請求方法,例如 OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, 和CONNECT

  • URL,例如http://www.apple.com

  • HTTP 版本,例如1.0版本或1.1版本。

  • 消息的標題通常根據標題名稱指定,例如User-Agent,或值,例如MyUserAgent

  • 消息主體

消息創建后,將其序列化。序列化后,請求如下:
<pre><code>GET / HTTP/1.0\r\nUser-Agent: UserAgent\r\nContent-Length: 0\r\n\r\n
</pre></code>

序列化對應的是反序列化。反序列化是將從客戶端或服務器接收到的原始字節流恢復成本地的表述。CFNetwork提供獲取消息類型(請求或響應),HTTP版本,URL,進入的序列化的消息的標題和主體所需要的所有功能。

使用CFHTTP的更多例子在與HTTP服務通信(Communicating with HTTP Servers)。

CFHTTPAuthentication API

如果你發送一個HTTP請求到身份驗證服務器而沒有認證信息(或不正確的認證信息),服務器將返回身份驗證懷疑(俗稱401或407響應)。CFHTTPAuthentication API向受到懷疑的HTTP消息提出身份驗證申請。CFHTTPAuthentication 支持如下身份驗證方案:

  • 基本

  • 摘要

  • NT LAN管理(NTLM)

  • 簡單的受保護的GSS-API 談判機制(SPNEGO)

OS X v10.4的新功能是提供持續請求功能。在OS X v10.3中,每次請求被懷疑,你必須從頭開始身份驗證。現在,你為每個服務器維護一組CFHTTPAuthentication 對象。當你收到一個401或407響應,你查找服務器正確的對象和憑證,并請求。CFNetwork使用存儲在對象的信息盡可能高效的處理請求。

通過持續請求,新版本的CFHTTPAuthentication 提供更好的性能。關于如何使用CFHTTPAuthentication 的更多信息,可查看與身份驗證HTTP服務器進行通信(Communicating with Authenticating HTTP Servers)。

CFHost API

你使用CFHost API獲取主機信息,包括名稱、地址和可達性信息。獲取信息的過程被稱為解析。

CFHost 與CFStream類似:

  • 創建CFHost 對象

  • 開始解析CFHost 對象

  • 檢索地址、主機名或可達性信息

  • 當你完成時,銷毀CFHost 對象

像所有的CFNetwork、CFHost都兼容IPv4 和IPv6 。使用CFHost,你可以編寫代碼完全透明的處理IPv4 和IPv6 。

CFHost的集成與CFNetwork密切相關。例如,有個稱為CFStreamCreatePairWithSocketToCFHost 的CFStream 函數會從CFHost對象中直接創建一個CFStream 對象。關于CFHost對象函數的更多信息,參見CFHost引用(CFHost Reference)。

CFNetServices API

如果你想讓你的應用使用Bonjour 注冊一個服務或發現服務可以使用CFNetServices API。Bonjour 是蘋果零配置網絡(ZEROCONF)的實現,它允許你發布、發現和解析網絡服務。

為了實現Bonjour ,CFNetServices API定義三個對象類型:CFNetService、CFNetServiceBrowser和CFNetServiceMonitor。CFNetService對象表示一個單一的網絡服務,例如打印機或文件服務器。它包含另一臺計算機解析服務器所需的所有信息,例如名稱、類型、域和域內網絡服務。CFNetServiceBrowser是一個對象用于發現域或域內網絡服務。CFNetServiceMonitor對象用于監控CFNetService 對象的變化,例如iChat中的狀態消息。

詳細Bonjour的描述見Bonjour概覽(Bonjour Overview)。關于使用CFNetServices 實現Bonjour的更多信息,可查看NSNetServices和CFNetServices編程指南(NSNetServices and CFNetServices Programming Guide)。

CFNetDiagnostics API

連接到網絡的應用依賴于一個穩定的鏈接。如果網絡不穩定,這將導致應用程序的問題。采用CFNetDiagnostics API,用戶可以自己診斷如下網絡問題:

  • 物理連接失敗(例如,未插入電纜)

  • 網絡故障(例如,DNS或DHCP服務器不再響應)

  • 配置失敗(例如,代理配置不正確)

一旦網絡故障診斷出來,CFNetDiagnostics 指導用戶解決問題。如果Safari連接網站失敗,你可能會看到CFNetDiagnostics 起作用。CFNetDiagnostics 助手如圖1-3所示。

圖1-3 網絡診斷助手

通過CFNetDiagnostics 提供的網絡故障內容,你可以調用CFNetDiagnosticDiagnoseProblemInteractively 函數引導用戶通過提示找到解決辦法。此外,你可以使用CFNetDiagnostics 查詢連接狀態并為用戶提供統一的錯誤消息。

如何集成CFNetDiagnotics 到你的應用,可參閱使用網絡診斷( Using Network Diagnostics)。CFNetDiagnostics 是OS X v10.4中新的API。

官方原文地址:

https://developer.apple.com/library/ios/documentation/Networking/Conceptual/CFNetwork/Concepts/Concepts.html#//apple_ref/doc/uid/TP30001132-CH4-SW10

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容