CFNetwork框架詳細(xì)解析(三) —— CFNetwork編程指導(dǎo)之CFNetwork概念(二)

版本記錄

版本號(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)化諸如與FTPHTTP服務(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所示。

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

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-levelAPI更側(cè)重于數(shù)據(jù)訪問(wèn),例如通過(guò)HTTPFTP傳輸數(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框架的一部分,即CFSocketCFStream。 理解這些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:CFReadStreamCFWriteStream。這兩種類型的流均遵循所有常用的Core Foundation API約定。有關(guān)Core Foundation類型的更多信息,請(qǐng)閱讀Core Foundation Design Concepts

CFStream建立在CFSocket之上,是CFHTTPCFFTP的基礎(chǔ)。如圖1-2所示,盡管CFStream不是CFNetwork的正式組成部分,它也是幾乎所有CFNetwork的基礎(chǔ)。

Figure 1-2 CFStream API structure

您可以像使用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í)返回的讀取流引用CFReadStreamRefCFReadStreamRead函數(shù)使用FTP服務(wù)器的輸出填充緩沖區(qū)。

有關(guān)使用CFFTP的更多信息,請(qǐng)參閱Working with FTP Servers

2. CFHTTP API

要發(fā)送和接收HTTP消息,請(qǐng)使用CFHTTP API。就像CFFTPFTP協(xié)議的抽象一樣,CFHTTPHTTP協(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ì)詢(通常稱為401407響應(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與IPv4IPv6兼容。 使用CFHost,您可以編寫(xiě)完全透明地處理IPv4和IPv6的代碼。

CFHost與CFNetwork的其他部分緊密結(jié)合。 例如,有一個(gè)名為CFStreamCreatePairWithSocketToCFHostCFStream函數(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)BonjourCFNetServices API定義了三種對(duì)象類型:CFNetServiceCFNetServiceBrowserCFNetServiceMonitorCFNetService對(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ò)故障(例如,DNSDHCP服務(wù)器不再響應(yīng))
  • 配置失敗(例如,代理配置不正確)

一旦診斷出網(wǎng)絡(luò)故障,CFNetDiagnostics將指導(dǎo)用戶解決問(wèn)題。 如果Safari無(wú)法連接到網(wǎng)站,您可能已經(jīng)看到CFNetDiagnostics正在運(yùn)行。 CFNetDiagnostics助手可以在圖1-3中看到。

Figure 1-3 Network diagnostics assistant

通過(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 DiagnosticsCFNetDiagnosticsOS X v10.4中的一個(gè)新API。

后記

本篇主要講述了CFNetwork的一些概念,感興趣的給個(gè)贊或者關(guān)注~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,702評(píng)論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,615評(píng)論 3 419
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,606評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,044評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,826評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,227評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,307評(píng)論 3 442
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,447評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,992評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,807評(píng)論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,001評(píng)論 1 370
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,550評(píng)論 5 361
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,243評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,667評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,930評(píng)論 1 287
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,709評(píng)論 3 393
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,996評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容