CFNetwork框架詳細解析(三) —— CFNetwork編程指導之CFNetwork概念(二)

版本記錄

版本號 時間
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,提供對象以簡化諸如與FTPHTTP服務器通信或解析DNS主機等任務妒挎。 CFNetwork在物理和理論上都基于BSD套接字绳锅。

正如CFNetwork依賴于BSD套接字一樣,有許多Cocoa類依賴于CFNetwork(例如NSURL)酝掩。 另外鳞芙,Web Kit是一組Cocoa類,用于在Windows中顯示W(wǎng)eb內容期虾。 這兩個類都是非常高的級別原朝,并且自己實現(xiàn)了網(wǎng)絡協(xié)議的大部分細節(jié)。 因此镶苞,軟件層的結構如圖1-1所示喳坠。

Figure 1-1 CFNetwork and other software layers on OS X

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-levelAPI更側重于數(shù)據(jù)訪問数尿,例如通過HTTPFTP傳輸數(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框架的一部分剥扣,即CFSocketCFStream巩剖。 理解這些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:CFReadStreamCFWriteStream荧飞。這兩種類型的流均遵循所有常用的Core Foundation API約定。有關Core Foundation類型的更多信息名党,請閱讀Core Foundation Design Concepts叹阔。

CFStream建立在CFSocket之上,是CFHTTPCFFTP的基礎传睹。如圖1-2所示耳幢,盡管CFStream不是CFNetwork的正式組成部分,它也是幾乎所有CFNetwork的基礎欧啤。

Figure 1-2 CFStream API structure

您可以像使用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腹纳。就像CFFTPFTP協(xié)議的抽象一樣痢掠,CFHTTPHTTP協(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ù)不正確),則服務器會返回授權質詢(通常稱為401407響應)徙缴。 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與IPv4IPv6兼容浦译。 使用CFHost棒假,您可以編寫完全透明地處理IPv4和IPv6的代碼。

CFHost與CFNetwork的其他部分緊密結合精盅。 例如帽哑,有一個名為CFStreamCreatePairWithSocketToCFHostCFStream函數(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)BonjourCFNetServices API定義了三種對象類型:CFNetService顶伞,CFNetServiceBrowserCFNetServiceMonitor饵撑。 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)絡故障(例如蔫仙,DNSDHCP服務器不再響應)
  • 配置失敗(例如丐箩,代理配置不正確)

一旦診斷出網(wǎng)絡故障摇邦,CFNetDiagnostics將指導用戶解決問題。 如果Safari無法連接到網(wǎng)站屎勘,您可能已經(jīng)看到CFNetDiagnostics正在運行施籍。 CFNetDiagnostics助手可以在圖1-3中看到。

Figure 1-3 Network diagnostics assistant

通過為網(wǎng)絡故障的上下文提供CFNetDiagnostics概漱,您可以調用CFNetDiagnosticDiagnoseProblemInteractively函數(shù)來引導用戶完成提示以找到解決方案丑慎。 此外,您可以使用CFNetDiagnostics查詢連接狀態(tài)并向用戶提供統(tǒng)一的錯誤消息瓤摧。

要了解如何將CFNetDiagnotics集成到您的應用程序中竿裂,請閱讀Using Network DiagnosticsCFNetDiagnosticsOS X v10.4中的一個新API照弥。

后記

本篇主要講述了CFNetwork的一些概念铛绰,感興趣的給個贊或者關注~~~

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市产喉,隨后出現(xiàn)的幾起案子捂掰,更是在濱河造成了極大的恐慌敢会,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件这嚣,死亡現(xiàn)場離奇詭異鸥昏,居然都是意外死亡,警方通過查閱死者的電腦和手機姐帚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門吏垮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人罐旗,你說我怎么就攤上這事膳汪。” “怎么了九秀?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵遗嗽,是天一觀的道長。 經(jīng)常有香客問我鼓蜒,道長痹换,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任都弹,我火速辦了婚禮娇豫,結果婚禮上,老公的妹妹穿的比我還像新娘畅厢。我一直安慰自己冯痢,他們只是感情好,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布框杜。 她就那樣靜靜地躺著系羞,像睡著了一般馍资。 火紅的嫁衣襯著肌膚如雪废膘。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天布隔,我揣著相機與錄音梧乘,去河邊找鬼澎迎。 笑死,一個胖子當著我的面吹牛选调,可吹牛的內容都是我干的夹供。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼仁堪,長吁一口氣:“原來是場噩夢啊……” “哼哮洽!你這毒婦竟也來了?” 一聲冷哼從身側響起弦聂,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤鸟辅,失蹤者是張志新(化名)和其女友劉穎氛什,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匪凉,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡枪眉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了再层。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贸铜。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖聂受,靈堂內的尸體忽然破棺而出蒿秦,到底是詐尸還是另有隱情,我是刑警寧澤蛋济,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布棍鳖,位于F島的核電站,受9級特大地震影響瘫俊,放射性物質發(fā)生泄漏。R本人自食惡果不足惜悴灵,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一扛芽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧积瞒,春花似錦川尖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至缰贝,卻和暖如春馍悟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背剩晴。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工锣咒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赞弥。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓毅整,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绽左。 傳聞我的和親對象是個殘疾皇子悼嫉,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容