CFNetwork框架详细解析(三) —— CFNetwork编程指导之CFNetwork概念(二)

版本记录

版本号 时间
V1.0 2018.06.08

前言

CFNetwork框架访问网络服务并处理网络配置的变化。 建立在网络协议抽象的基础上,可以简化诸如使用BSD套接字,管理HTTP和FTP服务器以及管理Bonjour服务等任务。接下来几篇我们就一起看一下这个框架。感兴趣的可以看上面几篇文章。
1. CFNetwork框架详细解析(一) —— 基本概览
2. CFNetwork框架详细解析(二) —— CFNetwork编程指导之简介(一)

CFNetwork Concepts - CFNetwork概念

CFNetwork是一个低级别,高性能的框架,使您能够对协议栈进行详细控制。 它是BSD套接字的扩展,BSD套接字是标准套接字抽象API,提供对象以简化诸如与FTPHTTP服务器通信或解析DNS主机等任务。 CFNetwork在物理和理论上都基于BSD套接字。

正如CFNetwork依赖于BSD套接字一样,有许多Cocoa类依赖于CFNetwork(例如NSURL)。 另外,Web Kit是一组Cocoa类,用于在Windows中显示Web内容。 这两个类都是非常高的级别,并且自己实现了网络协议的大部分细节。 因此,软件层的结构如图1-1所示。

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

When to Use CFNetwork - 何时使用CFNetwork

CFNetwork比BSD套接字有许多优点。它提供了运行循环集成,所以如果你的应用程序是基于循环运行的,你可以使用网络协议而不需要实现线程。 CFNetwork还包含许多对象,可帮助您使用网络协议,而无需自行实施细节。例如,您可以使用FTP协议,而无需使用CFFTP API实现所有细节。如果您了解网络协议并需要他们提供的低级控制,但不想自己实施,那么CFNetwork可能是正确的选择。

使用CFNetwork而不是Foundation-level网络API有许多优点。 CFNetwork更侧重于网络协议,而Foundation-levelAPI更侧重于数据访问,例如通过HTTPFTP传输数据。虽然Foundation API确实提供了一些可配置性,但CFNetwork提供了更多。有关Foundation网络类的更多信息,请阅读URL Loading System

现在您已了解CFNetwork如何与其他OS X网络API交互,您已准备好熟悉CFNetwork API以及两个构成CFNetwork基础结构的API。


CFNetwork Infrastructure - CFNetwork基础结构

在了解CFNetwork API之前,您必须首先了解作为CFNetwork主要结构的API。 CFNetwork依赖于两个API,它们是Core Foundation框架的一部分,即CFSocketCFStream。 理解这些API对于使用CFNetwork是至关重要的。

1. CFSocket API

Sockets是最基本的网络通信级别。socket的作用与电话插孔类似。它允许您连接到另一个套接字(本地或通过网络)并将数据发送到该套接字。

最常见的套接字抽象是BSD套接字。 CFSocket是BSD套接字的抽象。几乎没有开销,CFSocket几乎提供了BSD套接字的所有功能,并将套接字集成到运行循环中。 CFSocket不限于基于流的套接字(例如TCP),它可以处理任何类型的套接字。

您可以使用CFSocketCreate函数从头开始创建CFSocket对象,也可以使用CFSocketCreateWithNative函数从BSD套接字创建CFSocket对象。然后,您可以使用函数CFSocketCreateRunLoopSource创建一个运行循环源,并使用函数CFRunLoopAddSource将其添加到运行循环中。这将允许您的CFSocket回调函数在CFSocket对象收到消息时运行。

阅读CFSocket Reference了解关于CFSocket API的更多信息。

2. CFStream API

读取和写入流提供了一种以独立于设备的方式与各种媒体交换数据的简单方法。您可以为位于内存中,文件中或网络上(使用套接字)的数据创建流,并且可以使用流,而无需将所有数据一次加载到内存中。

流是通过通信路径串行传输的字节序列。流是单向路径,所以双向通信输入(读)流和输出(写)流是必需的。除了基于文件的流,您不能在流中搜索;一旦流数据已被提供或消耗,就不能再从流中检索它。

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文件描述符一样使用读取和写入流。首先,通过指定流类型(内存,文件或套接字)并设置任何选项来实例化流。接下来,您打开流并读取或写入任意次数。当流存在时,您可以通过询问其属性来获取有关流的信息。流属性是关于流的任何信息,例如源或目标,这些信息不是正在读取或写入的实际数据的一部分。当你不再需要流时,关闭并处理它。

读取或写入流的CFStream函数将挂起或阻塞当前进程,直到至少可以读取或写入一个字节的数据。为避免在流阻塞时尝试读取或写入流,请使用函数的异步版本并在运行循环中调度流。您可以在不阻塞的情况下读取和写入您的回调函数。

另外,CFStream还内置了对Secure Sockets Layer(SSL)协议的支持。您可以设置包含流的SSL信息的字典,例如所需的安全级别或自签名证书。然后将它作为kCFStreamPropertySSLSettings属性传递给您的流,以使流成为SSL流。

Working with Streams一章介绍了如何使用读取和写入流。


CFNetwork API Concepts - CFNetwork API概念

要理解CFNetwork框架,您需要熟悉组成它的构建块。 CFNetwork框架被分解成单独的API,每个都包含特定的网络协议。 这些API可以组合使用,也可以分开使用,具体取决于您的应用程序。 大多数编程约定在API中很常见,所以理解其中的每一个都很重要。

1. 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读取流创建时指定的FTP服务器的连接,请调用函数CFReadStreamOpen。要从流中读取数据,请使用CFReadStreamRead函数并提供在创建FTP读取流时返回的读取流引用CFReadStreamRefCFReadStreamRead函数使用FTP服务器的输出填充缓冲区。

有关使用CFFTP的更多信息,请参阅Working with FTP Servers

2. CFHTTP API

要发送和接收HTTP消息,请使用CFHTTP API。就像CFFTPFTP协议的抽象一样,CFHTTPHTTP协议的抽象。

超文本传输​​协议Hypertext Transfer Protocol(HTTP)是客户端和服务器之间的请求/响应协议。客户端创建一个请求消息。然后序列化该消息,这是一个将消息转换为原始字节流的过程。消息只有先序列化后才能发送。然后请求消息被发送到服务器。该请求通常会询问文件,例如网页。服务器响应,返回一个字符串,后面跟着一条消息。这个过程可以根据需要重复多次。

要创建HTTP请求消息,请指定以下内容:

  • 请求方法可以是超文本传输​​协议定义的请求方法之一,例如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

反序列化与序列化相反。通过反序列化,从客户端或服务器接收到的原始字节流将恢复为其本机表示。 CFNetwork提供了从传入的序列化消息中获取消息类型(请求或响应),HTTP版本,URL,头和正文所需的所有功能。

Communicating with HTTP Servers中提供了更多使用CFHTTP的示例。

3. CFHTTPAuthentication API

如果您将HTTP请求发送到没有凭据的身份验证服务器(或凭据不正确),则服务器会返回授权质询(通常称为401407响应)。 CFHTTPAuthentication API将身份验证凭证应用于挑战HTTP消息。 CFHTTPAuthentication支持以下认证方案:

  • Basic
  • Digest
  • NT LAN Manager (NTLM)
  • Simple and Protected GSS-API Negotiation Mechanism (SPNEGO)

OS X v10.4中的新功能是能够跨请求执行持久性。在OS X v10.3中,每次请求遭到质疑时,您都必须从头开始验证对话框。现在,您为每个服务器维护一组CFHTTPAuthentication对象。当您收到401或407响应时,您会找到该服务器的正确对象和凭据并应用它们。 CFNetwork使用该对象中存储的信息尽可能高效地处理请求。

通过在请求中保持持久性,这个新版本的CFHTTPAuthentication提供了更好的性能。有关如何使用CFHTTPAuthentication的更多信息,请参阅Communicating with Authenticating HTTP Servers

4. CFHost API

您使用CFHost API来获取主机信息,包括名称,地址和可访问性信息。 获取关于host的信息的过程称为resolution

CFHost就像CFStream一样使用:

  • 创建一个CFHost对象。
  • 开始解析CFHost对象。
  • 检索地址,主机名或可访问性信息。
  • 完成后销毁CFHost对象。

像所有CFNetwork一样,CFHost与IPv4IPv6兼容。 使用CFHost,您可以编写完全透明地处理IPv4和IPv6的代码。

CFHost与CFNetwork的其他部分紧密结合。 例如,有一个名为CFStreamCreatePairWithSocketToCFHostCFStream函数,它将直接从CFHost对象创建一个CFStream对象。 有关CFHost对象函数的更多信息,请参阅CFHost Reference

5. CFNetServices API

如果您希望应用程序使用Bonjour注册服务或发现服务,请使用CFNetServices API。 Bonjour是Apple实施的零配置网络(ZEROCONF),它允许您发布,发现和解析网络服务。

为了实现BonjourCFNetServices API定义了三种对象类型:CFNetServiceCFNetServiceBrowserCFNetServiceMonitorCFNetService对象表示单个网络服务,如打印机或文件服务器。它包含另一台计算机解析该服务器所需的所有信息,例如名称,类型,域和端口号。 CFNetServiceBrowser是用于发现域内的域和网络服务的对象。 CFNetServiceMonitor对象用于监视CFNetService对象的更改,例如iChat中的状态消息。

有关Bonjour的完整描述,请参阅Bonjour Overview。有关使用CFNetServices和实现Bonjour的更多信息,请参阅 NSNetServices and CFNetServices Programming Guide

6. CFNetDiagnostics API

连接到网络的应用程序取决于稳定的连接。 如果网络出现故障,这会导致应用程序出现问题。 通过采用CFNetDiagnostics API,用户可以自我诊断网络问题,例如:

  • 物理连接失败(例如,电缆被拔出)
  • 网络故障(例如,DNSDHCP服务器不再响应)
  • 配置失败(例如,代理配置不正确)

一旦诊断出网络故障,CFNetDiagnostics将指导用户解决问题。 如果Safari无法连接到网站,您可能已经看到CFNetDiagnostics正在运行。 CFNetDiagnostics助手可以在图1-3中看到。

Figure 1-3 Network diagnostics assistant

通过为网络故障的上下文提供CFNetDiagnostics,您可以调用CFNetDiagnosticDiagnoseProblemInteractively函数来引导用户完成提示以找到解决方案。 此外,您可以使用CFNetDiagnostics查询连接状态并向用户提供统一的错误消息。

要了解如何将CFNetDiagnotics集成到您的应用程序中,请阅读Using Network DiagnosticsCFNetDiagnosticsOS X v10.4中的一个新API。

后记

本篇主要讲述了CFNetwork的一些概念,感兴趣的给个赞或者关注~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容