版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2018.06.08 |
前言
CFNetwork框架訪問(wèn)網(wǎng)絡(luò)服務(wù)并處理網(wǎng)絡(luò)配置的變化。 建立在網(wǎng)絡(luò)協(xié)議抽象的基礎(chǔ)上,可以簡(jiǎn)化諸如使用BSD套接字,管理HTTP和FTP服務(wù)器以及管理Bonjour服務(wù)等任務(wù)。接下來(lái)幾篇我們就一起看一下這個(gè)框架。感興趣的可以看上面幾篇文章。
1. CFNetwork框架詳細(xì)解析(一) —— 基本概覽
2. CFNetwork框架詳細(xì)解析(二) —— CFNetwork編程指導(dǎo)之簡(jiǎn)介(一)
CFNetwork Concepts - CFNetwork概念
CFNetwork是一個(gè)低級(jí)別,高性能的框架,使您能夠?qū)f(xié)議棧進(jìn)行詳細(xì)控制。 它是BSD套接字的擴(kuò)展,BSD套接字是標(biāo)準(zhǔn)套接字抽象API,提供對(duì)象以簡(jiǎn)化諸如與FTP
和HTTP
服務(wù)器通信或解析DNS
主機(jī)等任務(wù)。 CFNetwork在物理和理論上都基于BSD
套接字。
正如CFNetwork
依賴于BSD套接字一樣,有許多Cocoa類依賴于CFNetwork
(例如NSURL)。 另外,Web Kit是一組Cocoa類,用于在Windows中顯示W(wǎng)eb內(nèi)容。 這兩個(gè)類都是非常高的級(jí)別,并且自己實(shí)現(xiàn)了網(wǎng)絡(luò)協(xié)議的大部分細(xì)節(jié)。 因此,軟件層的結(jié)構(gòu)如圖1-1所示。
When to Use CFNetwork - 何時(shí)使用CFNetwork
CFNetwork
比BSD套接字有許多優(yōu)點(diǎn)。它提供了運(yùn)行循環(huán)集成,所以如果你的應(yīng)用程序是基于循環(huán)運(yùn)行的,你可以使用網(wǎng)絡(luò)協(xié)議而不需要實(shí)現(xiàn)線程。 CFNetwork
還包含許多對(duì)象,可幫助您使用網(wǎng)絡(luò)協(xié)議,而無(wú)需自行實(shí)施細(xì)節(jié)。例如,您可以使用FTP
協(xié)議,而無(wú)需使用CFFTP API
實(shí)現(xiàn)所有細(xì)節(jié)。如果您了解網(wǎng)絡(luò)協(xié)議并需要他們提供的低級(jí)控制,但不想自己實(shí)施,那么CFNetwork可能是正確的選擇。
使用CFNetwork而不是Foundation-level
網(wǎng)絡(luò)API有許多優(yōu)點(diǎn)。 CFNetwork更側(cè)重于網(wǎng)絡(luò)協(xié)議,而Foundation-level
API更側(cè)重于數(shù)據(jù)訪問(wèn),例如通過(guò)HTTP
或FTP
傳輸數(shù)據(jù)。雖然Foundation API
確實(shí)提供了一些可配置性,但CFNetwork提供了更多。有關(guān)Foundation
網(wǎng)絡(luò)類的更多信息,請(qǐng)閱讀URL Loading System
。
現(xiàn)在您已了解CFNetwork如何與其他OS X網(wǎng)絡(luò)API交互,您已準(zhǔn)備好熟悉CFNetwork API
以及兩個(gè)構(gòu)成CFNetwork基礎(chǔ)結(jié)構(gòu)的API。
CFNetwork Infrastructure - CFNetwork基礎(chǔ)結(jié)構(gòu)
在了解CFNetwork API
之前,您必須首先了解作為CFNetwork主要結(jié)構(gòu)的API。 CFNetwork依賴于兩個(gè)API,它們是Core Foundation
框架的一部分,即CFSocket
和CFStream
。 理解這些API對(duì)于使用CFNetwork是至關(guān)重要的。
1. CFSocket API
Sockets
是最基本的網(wǎng)絡(luò)通信級(jí)別。socket
的作用與電話插孔類似。它允許您連接到另一個(gè)套接字(本地或通過(guò)網(wǎng)絡(luò))并將數(shù)據(jù)發(fā)送到該套接字。
最常見(jiàn)的套接字抽象是BSD套接字。 CFSocket是BSD套接字的抽象。幾乎沒(méi)有開(kāi)銷,CFSocket幾乎提供了BSD套接字的所有功能,并將套接字集成到運(yùn)行循環(huán)中。 CFSocket不限于基于流的套接字(例如TCP),它可以處理任何類型的套接字。
您可以使用CFSocketCreate
函數(shù)從頭開(kāi)始創(chuàng)建CFSocket對(duì)象,也可以使用CFSocketCreateWithNative
函數(shù)從BSD套接字創(chuàng)建CFSocket對(duì)象。然后,您可以使用函數(shù)CFSocketCreateRunLoopSource
創(chuàng)建一個(gè)運(yùn)行循環(huán)源,并使用函數(shù)CFRunLoopAddSource
將其添加到運(yùn)行循環(huán)中。這將允許您的CFSocket
回調(diào)函數(shù)在CFSocket對(duì)象收到消息時(shí)運(yùn)行。
閱讀CFSocket Reference了解關(guān)于CFSocket API
的更多信息。
2. CFStream API
讀取和寫(xiě)入流提供了一種以獨(dú)立于設(shè)備的方式與各種媒體交換數(shù)據(jù)的簡(jiǎn)單方法。您可以為位于內(nèi)存中,文件中或網(wǎng)絡(luò)上(使用套接字)的數(shù)據(jù)創(chuàng)建流,并且可以使用流,而無(wú)需將所有數(shù)據(jù)一次加載到內(nèi)存中。
流是通過(guò)通信路徑串行傳輸?shù)淖止?jié)序列。流是單向路徑,所以雙向通信輸入(讀)流和輸出(寫(xiě))流是必需的。除了基于文件的流,您不能在流中搜索;一旦流數(shù)據(jù)已被提供或消耗,就不能再?gòu)牧髦袡z索它。
CFStream
是一個(gè)使用兩個(gè)新的CFType
對(duì)象為這些流提供抽象的API:CFReadStream
和CFWriteStream
。這兩種類型的流均遵循所有常用的Core Foundation API
約定。有關(guān)Core Foundation
類型的更多信息,請(qǐng)閱讀Core Foundation Design Concepts。
CFStream
建立在CFSocket
之上,是CFHTTP
和CFFTP
的基礎(chǔ)。如圖1-2所示,盡管CFStream
不是CFNetwork
的正式組成部分,它也是幾乎所有CFNetwork
的基礎(chǔ)。
您可以像使用UNIX
文件描述符一樣使用讀取和寫(xiě)入流。首先,通過(guò)指定流類型(內(nèi)存,文件或套接字)并設(shè)置任何選項(xiàng)來(lái)實(shí)例化流。接下來(lái),您打開(kāi)流并讀取或?qū)懭肴我獯螖?shù)。當(dāng)流存在時(shí),您可以通過(guò)詢問(wèn)其屬性來(lái)獲取有關(guān)流的信息。流屬性是關(guān)于流的任何信息,例如源或目標(biāo),這些信息不是正在讀取或?qū)懭氲膶?shí)際數(shù)據(jù)的一部分。當(dāng)你不再需要流時(shí),關(guān)閉并處理它。
讀取或?qū)懭肓鞯?code>CFStream函數(shù)將掛起或阻塞當(dāng)前進(jìn)程,直到至少可以讀取或?qū)懭胍粋€(gè)字節(jié)的數(shù)據(jù)。為避免在流阻塞時(shí)嘗試讀取或?qū)懭肓鳎?qǐng)使用函數(shù)的異步版本并在運(yùn)行循環(huán)中調(diào)度流。您可以在不阻塞的情況下讀取和寫(xiě)入您的回調(diào)函數(shù)。
另外,CFStream
還內(nèi)置了對(duì)Secure Sockets Layer(SSL)
協(xié)議的支持。您可以設(shè)置包含流的SSL信息的字典,例如所需的安全級(jí)別或自簽名證書(shū)。然后將它作為kCFStreamPropertySSLSettings
屬性傳遞給您的流,以使流成為SSL流。
Working with Streams一章介紹了如何使用讀取和寫(xiě)入流。
CFNetwork API Concepts - CFNetwork API概念
要理解CFNetwork框架,您需要熟悉組成它的構(gòu)建塊。 CFNetwork框架被分解成單獨(dú)的API,每個(gè)都包含特定的網(wǎng)絡(luò)協(xié)議。 這些API可以組合使用,也可以分開(kāi)使用,具體取決于您的應(yīng)用程序。 大多數(shù)編程約定在API中很常見(jiàn),所以理解其中的每一個(gè)都很重要。
1. CFFTP API
使用CFFTP
可以更輕松地與FTP服務(wù)器進(jìn)行通信。使用CFFTP API
,您可以創(chuàng)建FTP
讀取流(用于下載)和FTP
寫(xiě)入流(用于上傳)。使用FTP讀寫(xiě)流,您可以執(zhí)行以下功能:
- 從FTP服務(wù)器下載文件
- 上傳文件到FTP服務(wù)器
- 從FTP服務(wù)器下載文件夾列表
- 在FTP服務(wù)器上創(chuàng)建文件夾
一個(gè)FTP流與所有其他CFNetwork流一樣。例如,您可以通過(guò)調(diào)用函數(shù)CFReadStreamCreateWithFTPURL
函數(shù)來(lái)創(chuàng)建FTP讀取流。然后,您可以隨時(shí)調(diào)用函數(shù)CFReadStreamGetError
來(lái)檢查流的狀態(tài)。
通過(guò)設(shè)置FTP流的屬性,您可以調(diào)整您的流以適應(yīng)特定的應(yīng)用程序。例如,如果流正在連接的服務(wù)器需要用戶名和密碼,則需要設(shè)置適當(dāng)?shù)膶傩裕允乖摿骺梢哉9ぷ鳌S嘘P(guān)可用于FTP流的不同屬性的更多信息,請(qǐng)閱讀Setting up the Streams。
CFFTP流可以同步或異步使用。要打開(kāi)與FTP讀取流創(chuàng)建時(shí)指定的FTP服務(wù)器的連接,請(qǐng)調(diào)用函數(shù)CFReadStreamOpen
。要從流中讀取數(shù)據(jù),請(qǐng)使用CFReadStreamRead
函數(shù)并提供在創(chuàng)建FTP讀取流時(shí)返回的讀取流引用CFReadStreamRef
。 CFReadStreamRead
函數(shù)使用FTP服務(wù)器的輸出填充緩沖區(qū)。
有關(guān)使用CFFTP
的更多信息,請(qǐng)參閱Working with FTP Servers。
2. CFHTTP API
要發(fā)送和接收HTTP消息,請(qǐng)使用CFHTTP API
。就像CFFTP
是FTP
協(xié)議的抽象一樣,CFHTTP
是HTTP
協(xié)議的抽象。
超文本傳輸??協(xié)議Hypertext Transfer Protocol(HTTP)
是客戶端和服務(wù)器之間的請(qǐng)求/響應(yīng)協(xié)議。客戶端創(chuàng)建一個(gè)請(qǐng)求消息。然后序列化該消息,這是一個(gè)將消息轉(zhuǎn)換為原始字節(jié)流的過(guò)程。消息只有先序列化后才能發(fā)送。然后請(qǐng)求消息被發(fā)送到服務(wù)器。該請(qǐng)求通常會(huì)詢問(wèn)文件,例如網(wǎng)頁(yè)。服務(wù)器響應(yīng),返回一個(gè)字符串,后面跟著一條消息。這個(gè)過(guò)程可以根據(jù)需要重復(fù)多次。
要?jiǎng)?chuàng)建HTTP請(qǐng)求消息,請(qǐng)指定以下內(nèi)容:
- 請(qǐng)求方法可以是超文本傳輸??協(xié)議定義的請(qǐng)求方法之一,例如
OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE和CONNECT
- URL,例如
http://www.apple.com
-
HTTP
版本,如版本1.0或1.1 - 消息頭,通過(guò)指定頭名稱(如
User-Agent
)及其值(如MyUserAgent
) - 消息的正文
消息構(gòu)建完成后,將其序列化。序列化后,請(qǐng)求可能如下所示:
GET / HTTP/1.0\r\nUser-Agent: UserAgent\r\nContent-Length: 0\r\n\r\n
反序列化與序列化相反。通過(guò)反序列化,從客戶端或服務(wù)器接收到的原始字節(jié)流將恢復(fù)為其本機(jī)表示。 CFNetwork提供了從傳入的序列化消息中獲取消息類型(請(qǐng)求或響應(yīng)),HTTP版本,URL,頭和正文所需的所有功能。
Communicating with HTTP Servers中提供了更多使用CFHTTP
的示例。
3. CFHTTPAuthentication API
如果您將HTTP請(qǐng)求發(fā)送到?jīng)]有憑據(jù)的身份驗(yàn)證服務(wù)器(或憑據(jù)不正確),則服務(wù)器會(huì)返回授權(quán)質(zhì)詢(通常稱為401
或407
響應(yīng))。 CFHTTPAuthentication API
將身份驗(yàn)證憑證應(yīng)用于挑戰(zhàn)HTTP消息。 CFHTTPAuthentication
支持以下認(rèn)證方案:
Basic
Digest
NT LAN Manager (NTLM)
Simple and Protected GSS-API Negotiation Mechanism (SPNEGO)
OS X v10.4
中的新功能是能夠跨請(qǐng)求執(zhí)行持久性。在OS X v10.3
中,每次請(qǐng)求遭到質(zhì)疑時(shí),您都必須從頭開(kāi)始驗(yàn)證對(duì)話框。現(xiàn)在,您為每個(gè)服務(wù)器維護(hù)一組CFHTTPAuthentication
對(duì)象。當(dāng)您收到401或407響應(yīng)時(shí),您會(huì)找到該服務(wù)器的正確對(duì)象和憑據(jù)并應(yīng)用它們。 CFNetwork
使用該對(duì)象中存儲(chǔ)的信息盡可能高效地處理請(qǐng)求。
通過(guò)在請(qǐng)求中保持持久性,這個(gè)新版本的CFHTTPAuthentication
提供了更好的性能。有關(guān)如何使用CFHTTPAuthentication
的更多信息,請(qǐng)參閱Communicating with Authenticating HTTP Servers。
4. CFHost API
您使用CFHost API
來(lái)獲取主機(jī)信息,包括名稱,地址和可訪問(wèn)性信息。 獲取關(guān)于host的信息的過(guò)程稱為resolution
。
CFHost
就像CFStream
一樣使用:
- 創(chuàng)建一個(gè)
CFHost
對(duì)象。 - 開(kāi)始解析
CFHost
對(duì)象。 - 檢索地址,主機(jī)名或可訪問(wèn)性信息。
- 完成后銷毀
CFHost
對(duì)象。
像所有CFNetwork
一樣,CFHost與IPv4
和IPv6
兼容。 使用CFHost,您可以編寫(xiě)完全透明地處理IPv4和IPv6的代碼。
CFHost與CFNetwork的其他部分緊密結(jié)合。 例如,有一個(gè)名為CFStreamCreatePairWithSocketToCFHost
的CFStream
函數(shù),它將直接從CFHost
對(duì)象創(chuàng)建一個(gè)CFStream對(duì)象。 有關(guān)CFHost對(duì)象函數(shù)的更多信息,請(qǐng)參閱CFHost Reference
。
5. CFNetServices API
如果您希望應(yīng)用程序使用Bonjour
注冊(cè)服務(wù)或發(fā)現(xiàn)服務(wù),請(qǐng)使用CFNetServices API
。 Bonjour是Apple實(shí)施的零配置網(wǎng)絡(luò)(ZEROCONF)
,它允許您發(fā)布,發(fā)現(xiàn)和解析網(wǎng)絡(luò)服務(wù)。
為了實(shí)現(xiàn)Bonjour
,CFNetServices API
定義了三種對(duì)象類型:CFNetService
,CFNetServiceBrowser
和CFNetServiceMonitor
。 CFNetService
對(duì)象表示單個(gè)網(wǎng)絡(luò)服務(wù),如打印機(jī)或文件服務(wù)器。它包含另一臺(tái)計(jì)算機(jī)解析該服務(wù)器所需的所有信息,例如名稱,類型,域和端口號(hào)。 CFNetServiceBrowser
是用于發(fā)現(xiàn)域內(nèi)的域和網(wǎng)絡(luò)服務(wù)的對(duì)象。 CFNetServiceMonitor
對(duì)象用于監(jiān)視CFNetService
對(duì)象的更改,例如iChat
中的狀態(tài)消息。
有關(guān)Bonjour
的完整描述,請(qǐng)參閱Bonjour Overview。有關(guān)使用CFNetServices
和實(shí)現(xiàn)Bonjour
的更多信息,請(qǐng)參閱 NSNetServices and CFNetServices Programming Guide。
6. CFNetDiagnostics API
連接到網(wǎng)絡(luò)的應(yīng)用程序取決于穩(wěn)定的連接。 如果網(wǎng)絡(luò)出現(xiàn)故障,這會(huì)導(dǎo)致應(yīng)用程序出現(xiàn)問(wèn)題。 通過(guò)采用CFNetDiagnostics API
,用戶可以自我診斷網(wǎng)絡(luò)問(wèn)題,例如:
- 物理連接失敗(例如,電纜被拔出)
- 網(wǎng)絡(luò)故障(例如,
DNS
或DHCP
服務(wù)器不再響應(yīng)) - 配置失敗(例如,代理配置不正確)
一旦診斷出網(wǎng)絡(luò)故障,CFNetDiagnostics
將指導(dǎo)用戶解決問(wèn)題。 如果Safari
無(wú)法連接到網(wǎng)站,您可能已經(jīng)看到CFNetDiagnostics
正在運(yùn)行。 CFNetDiagnostics
助手可以在圖1-3中看到。
通過(guò)為網(wǎng)絡(luò)故障的上下文提供CFNetDiagnostics
,您可以調(diào)用CFNetDiagnosticDiagnoseProblemInteractively
函數(shù)來(lái)引導(dǎo)用戶完成提示以找到解決方案。 此外,您可以使用CFNetDiagnostics
查詢連接狀態(tài)并向用戶提供統(tǒng)一的錯(cuò)誤消息。
要了解如何將CFNetDiagnotics
集成到您的應(yīng)用程序中,請(qǐng)閱讀Using Network Diagnostics。 CFNetDiagnostics
是OS X v10.4
中的一個(gè)新API。
后記
本篇主要講述了CFNetwork的一些概念,感興趣的給個(gè)贊或者關(guān)注~~~