版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2018.06.08 |
前言
CFNetwork框架訪問網(wǎng)絡服務并處理網(wǎng)絡配置的變化造烁。 建立在網(wǎng)絡協(xié)議抽象的基礎上吃粒,可以簡化諸如使用BSD套接字沪哺,管理HTTP和FTP服務器以及管理Bonjour服務等任務阿迈。接下來幾篇我們就一起看一下這個框架典蜕。感興趣的可以看上面幾篇文章畦韭。
1. CFNetwork框架詳細解析(一) —— 基本概覽
2. CFNetwork框架詳細解析(二) —— CFNetwork編程指導之簡介(一)
CFNetwork Concepts - CFNetwork概念
CFNetwork是一個低級別疼蛾,高性能的框架,使您能夠對協(xié)議棧進行詳細控制廊驼。 它是BSD套接字的擴展据过,BSD套接字是標準套接字抽象API,提供對象以簡化諸如與FTP
和HTTP
服務器通信或解析DNS
主機等任務妒挎。 CFNetwork在物理和理論上都基于BSD
套接字绳锅。
正如CFNetwork
依賴于BSD套接字一樣,有許多Cocoa類依賴于CFNetwork
(例如NSURL)酝掩。 另外鳞芙,Web Kit是一組Cocoa類,用于在Windows中顯示W(wǎng)eb內容期虾。 這兩個類都是非常高的級別原朝,并且自己實現(xiàn)了網(wǎng)絡協(xié)議的大部分細節(jié)。 因此镶苞,軟件層的結構如圖1-1所示喳坠。
When to Use CFNetwork - 何時使用CFNetwork
CFNetwork
比BSD套接字有許多優(yōu)點。它提供了運行循環(huán)集成茂蚓,所以如果你的應用程序是基于循環(huán)運行的壕鹉,你可以使用網(wǎng)絡協(xié)議而不需要實現(xiàn)線程。 CFNetwork
還包含許多對象聋涨,可幫助您使用網(wǎng)絡協(xié)議晾浴,而無需自行實施細節(jié)。例如牍白,您可以使用FTP
協(xié)議脊凰,而無需使用CFFTP API
實現(xiàn)所有細節(jié)。如果您了解網(wǎng)絡協(xié)議并需要他們提供的低級控制茂腥,但不想自己實施狸涌,那么CFNetwork可能是正確的選擇切省。
使用CFNetwork而不是Foundation-level
網(wǎng)絡API有許多優(yōu)點。 CFNetwork更側重于網(wǎng)絡協(xié)議杈抢,而Foundation-level
API更側重于數(shù)據(jù)訪問数尿,例如通過HTTP
或FTP
傳輸數(shù)據(jù)。雖然Foundation API
確實提供了一些可配置性惶楼,但CFNetwork提供了更多右蹦。有關Foundation
網(wǎng)絡類的更多信息,請閱讀URL Loading System
歼捐。
現(xiàn)在您已了解CFNetwork如何與其他OS X網(wǎng)絡API交互何陆,您已準備好熟悉CFNetwork API
以及兩個構成CFNetwork基礎結構的API。
CFNetwork Infrastructure - CFNetwork基礎結構
在了解CFNetwork API
之前豹储,您必須首先了解作為CFNetwork主要結構的API贷盲。 CFNetwork依賴于兩個API,它們是Core Foundation
框架的一部分剥扣,即CFSocket
和CFStream
巩剖。 理解這些API對于使用CFNetwork是至關重要的。
1. CFSocket API
Sockets
是最基本的網(wǎng)絡通信級別钠怯。socket
的作用與電話插孔類似佳魔。它允許您連接到另一個套接字(本地或通過網(wǎng)絡)并將數(shù)據(jù)發(fā)送到該套接字。
最常見的套接字抽象是BSD套接字晦炊。 CFSocket是BSD套接字的抽象鞠鲜。幾乎沒有開銷,CFSocket幾乎提供了BSD套接字的所有功能断国,并將套接字集成到運行循環(huán)中贤姆。 CFSocket不限于基于流的套接字(例如TCP),它可以處理任何類型的套接字稳衬。
您可以使用CFSocketCreate
函數(shù)從頭開始創(chuàng)建CFSocket對象霞捡,也可以使用CFSocketCreateWithNative
函數(shù)從BSD套接字創(chuàng)建CFSocket對象。然后薄疚,您可以使用函數(shù)CFSocketCreateRunLoopSource
創(chuàng)建一個運行循環(huán)源碧信,并使用函數(shù)CFRunLoopAddSource
將其添加到運行循環(huán)中。這將允許您的CFSocket
回調函數(shù)在CFSocket對象收到消息時運行输涕。
閱讀CFSocket Reference了解關于CFSocket API
的更多信息。
2. CFStream API
讀取和寫入流提供了一種以獨立于設備的方式與各種媒體交換數(shù)據(jù)的簡單方法慨畸。您可以為位于內存中莱坎,文件中或網(wǎng)絡上(使用套接字)的數(shù)據(jù)創(chuàng)建流,并且可以使用流寸士,而無需將所有數(shù)據(jù)一次加載到內存中檐什。
流是通過通信路徑串行傳輸?shù)淖止?jié)序列碴卧。流是單向路徑,所以雙向通信輸入(讀)流和輸出(寫)流是必需的乃正。除了基于文件的流住册,您不能在流中搜索;一旦流數(shù)據(jù)已被提供或消耗,就不能再從流中檢索它瓮具。
CFStream
是一個使用兩個新的CFType
對象為這些流提供抽象的API:CFReadStream
和CFWriteStream
荧飞。這兩種類型的流均遵循所有常用的Core Foundation API
約定。有關Core Foundation
類型的更多信息名党,請閱讀Core Foundation Design Concepts叹阔。
CFStream
建立在CFSocket
之上,是CFHTTP
和CFFTP
的基礎传睹。如圖1-2所示耳幢,盡管CFStream
不是CFNetwork
的正式組成部分,它也是幾乎所有CFNetwork
的基礎欧啤。
您可以像使用UNIX
文件描述符一樣使用讀取和寫入流睛藻。首先,通過指定流類型(內存邢隧,文件或套接字)并設置任何選項來實例化流店印。接下來,您打開流并讀取或寫入任意次數(shù)府框。當流存在時吱窝,您可以通過詢問其屬性來獲取有關流的信息。流屬性是關于流的任何信息迫靖,例如源或目標院峡,這些信息不是正在讀取或寫入的實際數(shù)據(jù)的一部分。當你不再需要流時系宜,關閉并處理它照激。
讀取或寫入流的CFStream
函數(shù)將掛起或阻塞當前進程,直到至少可以讀取或寫入一個字節(jié)的數(shù)據(jù)盹牧。為避免在流阻塞時嘗試讀取或寫入流俩垃,請使用函數(shù)的異步版本并在運行循環(huán)中調度流。您可以在不阻塞的情況下讀取和寫入您的回調函數(shù)汰寓。
另外口柳,CFStream
還內置了對Secure Sockets Layer(SSL)
協(xié)議的支持。您可以設置包含流的SSL信息的字典有滑,例如所需的安全級別或自簽名證書跃闹。然后將它作為kCFStreamPropertySSLSettings
屬性傳遞給您的流,以使流成為SSL流。
Working with Streams一章介紹了如何使用讀取和寫入流望艺。
CFNetwork API Concepts - CFNetwork API概念
要理解CFNetwork框架苛秕,您需要熟悉組成它的構建塊。 CFNetwork框架被分解成單獨的API找默,每個都包含特定的網(wǎng)絡協(xié)議艇劫。 這些API可以組合使用,也可以分開使用惩激,具體取決于您的應用程序店煞。 大多數(shù)編程約定在API中很常見,所以理解其中的每一個都很重要咧欣。
1. CFFTP API
使用CFFTP
可以更輕松地與FTP服務器進行通信浅缸。使用CFFTP API
,您可以創(chuàng)建FTP
讀取流(用于下載)和FTP
寫入流(用于上傳)魄咕。使用FTP讀寫流衩椒,您可以執(zhí)行以下功能:
- 從FTP服務器下載文件
- 上傳文件到FTP服務器
- 從FTP服務器下載文件夾列表
- 在FTP服務器上創(chuàng)建文件夾
一個FTP流與所有其他CFNetwork流一樣。例如哮兰,您可以通過調用函數(shù)CFReadStreamCreateWithFTPURL
函數(shù)來創(chuàng)建FTP讀取流毛萌。然后,您可以隨時調用函數(shù)CFReadStreamGetError
來檢查流的狀態(tài)喝滞。
通過設置FTP流的屬性阁将,您可以調整您的流以適應特定的應用程序。例如右遭,如果流正在連接的服務器需要用戶名和密碼做盅,則需要設置適當?shù)膶傩裕允乖摿骺梢哉9ぷ骶焦S嘘P可用于FTP流的不同屬性的更多信息吹榴,請閱讀Setting up the Streams。
CFFTP流可以同步或異步使用滚婉。要打開與FTP讀取流創(chuàng)建時指定的FTP服務器的連接图筹,請調用函數(shù)CFReadStreamOpen
。要從流中讀取數(shù)據(jù)让腹,請使用CFReadStreamRead
函數(shù)并提供在創(chuàng)建FTP讀取流時返回的讀取流引用CFReadStreamRef
远剩。 CFReadStreamRead
函數(shù)使用FTP服務器的輸出填充緩沖區(qū)。
有關使用CFFTP
的更多信息骇窍,請參閱Working with FTP Servers瓜晤。
2. CFHTTP API
要發(fā)送和接收HTTP消息,請使用CFHTTP API
腹纳。就像CFFTP
是FTP
協(xié)議的抽象一樣痢掠,CFHTTP
是HTTP
協(xié)議的抽象哈恰。
超文本傳輸??協(xié)議Hypertext Transfer Protocol(HTTP)
是客戶端和服務器之間的請求/響應協(xié)議≈救海客戶端創(chuàng)建一個請求消息。然后序列化該消息蛔钙,這是一個將消息轉換為原始字節(jié)流的過程锌云。消息只有先序列化后才能發(fā)送。然后請求消息被發(fā)送到服務器吁脱。該請求通常會詢問文件桑涎,例如網(wǎng)頁。服務器響應兼贡,返回一個字符串攻冷,后面跟著一條消息。這個過程可以根據(jù)需要重復多次遍希。
要創(chuàng)建HTTP請求消息等曼,請指定以下內容:
- 請求方法可以是超文本傳輸??協(xié)議定義的請求方法之一,例如
OPTIONS凿蒜,GET禁谦,HEAD,POST废封,PUT州泊,DELETE,TRACE和CONNECT
- URL漂洋,例如
http://www.apple.com
-
HTTP
版本遥皂,如版本1.0或1.1 - 消息頭,通過指定頭名稱(如
User-Agent
)及其值(如MyUserAgent
) - 消息的正文
消息構建完成后刽漂,將其序列化演训。序列化后,請求可能如下所示:
GET / HTTP/1.0\r\nUser-Agent: UserAgent\r\nContent-Length: 0\r\n\r\n
反序列化與序列化相反爽冕。通過反序列化仇祭,從客戶端或服務器接收到的原始字節(jié)流將恢復為其本機表示。 CFNetwork提供了從傳入的序列化消息中獲取消息類型(請求或響應)颈畸,HTTP版本乌奇,URL,頭和正文所需的所有功能眯娱。
Communicating with HTTP Servers中提供了更多使用CFHTTP
的示例礁苗。
3. CFHTTPAuthentication API
如果您將HTTP請求發(fā)送到?jīng)]有憑據(jù)的身份驗證服務器(或憑據(jù)不正確),則服務器會返回授權質詢(通常稱為401
或407
響應)徙缴。 CFHTTPAuthentication API
將身份驗證憑證應用于挑戰(zhàn)HTTP消息试伙。 CFHTTPAuthentication
支持以下認證方案:
Basic
Digest
NT LAN Manager (NTLM)
Simple and Protected GSS-API Negotiation Mechanism (SPNEGO)
OS X v10.4
中的新功能是能夠跨請求執(zhí)行持久性嘁信。在OS X v10.3
中,每次請求遭到質疑時疏叨,您都必須從頭開始驗證對話框∨司福現(xiàn)在,您為每個服務器維護一組CFHTTPAuthentication
對象蚤蔓。當您收到401或407響應時卦溢,您會找到該服務器的正確對象和憑據(jù)并應用它們。 CFNetwork
使用該對象中存儲的信息盡可能高效地處理請求秀又。
通過在請求中保持持久性单寂,這個新版本的CFHTTPAuthentication
提供了更好的性能。有關如何使用CFHTTPAuthentication
的更多信息吐辙,請參閱Communicating with Authenticating HTTP Servers宣决。
4. CFHost API
您使用CFHost API
來獲取主機信息,包括名稱昏苏,地址和可訪問性信息尊沸。 獲取關于host的信息的過程稱為resolution
。
CFHost
就像CFStream
一樣使用:
- 創(chuàng)建一個
CFHost
對象贤惯。 - 開始解析
CFHost
對象椒丧。 - 檢索地址,主機名或可訪問性信息救巷。
- 完成后銷毀
CFHost
對象壶熏。
像所有CFNetwork
一樣,CFHost與IPv4
和IPv6
兼容浦译。 使用CFHost棒假,您可以編寫完全透明地處理IPv4和IPv6的代碼。
CFHost與CFNetwork的其他部分緊密結合精盅。 例如帽哑,有一個名為CFStreamCreatePairWithSocketToCFHost
的CFStream
函數(shù),它將直接從CFHost
對象創(chuàng)建一個CFStream對象叹俏。 有關CFHost對象函數(shù)的更多信息妻枕,請參閱CFHost Reference
。
5. CFNetServices API
如果您希望應用程序使用Bonjour
注冊服務或發(fā)現(xiàn)服務粘驰,請使用CFNetServices API
屡谐。 Bonjour是Apple實施的零配置網(wǎng)絡(ZEROCONF)
,它允許您發(fā)布蝌数,發(fā)現(xiàn)和解析網(wǎng)絡服務愕掏。
為了實現(xiàn)Bonjour
,CFNetServices API
定義了三種對象類型:CFNetService
顶伞,CFNetServiceBrowser
和CFNetServiceMonitor
饵撑。 CFNetService
對象表示單個網(wǎng)絡服務剑梳,如打印機或文件服務器。它包含另一臺計算機解析該服務器所需的所有信息滑潘,例如名稱垢乙,類型,域和端口號语卤。 CFNetServiceBrowser
是用于發(fā)現(xiàn)域內的域和網(wǎng)絡服務的對象侨赡。 CFNetServiceMonitor
對象用于監(jiān)視CFNetService
對象的更改,例如iChat
中的狀態(tài)消息粱侣。
有關Bonjour
的完整描述,請參閱Bonjour Overview蓖宦。有關使用CFNetServices
和實現(xiàn)Bonjour
的更多信息齐婴,請參閱 NSNetServices and CFNetServices Programming Guide。
6. CFNetDiagnostics API
連接到網(wǎng)絡的應用程序取決于穩(wěn)定的連接稠茂。 如果網(wǎng)絡出現(xiàn)故障柠偶,這會導致應用程序出現(xiàn)問題。 通過采用CFNetDiagnostics API
睬关,用戶可以自我診斷網(wǎng)絡問題诱担,例如:
- 物理連接失敗(例如电爹,電纜被拔出)
- 網(wǎng)絡故障(例如蔫仙,
DNS
或DHCP
服務器不再響應) - 配置失敗(例如丐箩,代理配置不正確)
一旦診斷出網(wǎng)絡故障摇邦,CFNetDiagnostics
將指導用戶解決問題。 如果Safari
無法連接到網(wǎng)站屎勘,您可能已經(jīng)看到CFNetDiagnostics
正在運行施籍。 CFNetDiagnostics
助手可以在圖1-3中看到。
通過為網(wǎng)絡故障的上下文提供CFNetDiagnostics
概漱,您可以調用CFNetDiagnosticDiagnoseProblemInteractively
函數(shù)來引導用戶完成提示以找到解決方案丑慎。 此外,您可以使用CFNetDiagnostics
查詢連接狀態(tài)并向用戶提供統(tǒng)一的錯誤消息瓤摧。
要了解如何將CFNetDiagnotics
集成到您的應用程序中竿裂,請閱讀Using Network Diagnostics。 CFNetDiagnostics
是OS X v10.4
中的一個新API照弥。
后記
本篇主要講述了CFNetwork的一些概念铛绰,感興趣的給個贊或者關注~~~