版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.06.08 |
前言
CFNetwork框架访问网络服务并处理网络配置的变化。 建立在网络协议抽象的基础上,可以简化诸如使用BSD套接字,管理HTTP和FTP服务器以及管理Bonjour服务等任务。接下来几篇我们就一起看一下这个框架。感兴趣的可以看上面几篇文章。
1. CFNetwork框架详细解析(一) —— 基本概览
2. CFNetwork框架详细解析(二) —— CFNetwork编程指导之简介(一)
CFNetwork Concepts - CFNetwork概念
CFNetwork是一个低级别,高性能的框架,使您能够对协议栈进行详细控制。 它是BSD套接字的扩展,BSD套接字是标准套接字抽象API,提供对象以简化诸如与FTP
和HTTP
服务器通信或解析DNS
主机等任务。 CFNetwork在物理和理论上都基于BSD
套接字。
正如CFNetwork
依赖于BSD套接字一样,有许多Cocoa类依赖于CFNetwork
(例如NSURL)。 另外,Web Kit是一组Cocoa类,用于在Windows中显示Web内容。 这两个类都是非常高的级别,并且自己实现了网络协议的大部分细节。 因此,软件层的结构如图1-1所示。
When to Use CFNetwork - 何时使用CFNetwork
CFNetwork
比BSD套接字有许多优点。它提供了运行循环集成,所以如果你的应用程序是基于循环运行的,你可以使用网络协议而不需要实现线程。 CFNetwork
还包含许多对象,可帮助您使用网络协议,而无需自行实施细节。例如,您可以使用FTP
协议,而无需使用CFFTP API
实现所有细节。如果您了解网络协议并需要他们提供的低级控制,但不想自己实施,那么CFNetwork可能是正确的选择。
使用CFNetwork而不是Foundation-level
网络API有许多优点。 CFNetwork更侧重于网络协议,而Foundation-level
API更侧重于数据访问,例如通过HTTP
或FTP
传输数据。虽然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
框架的一部分,即CFSocket
和CFStream
。 理解这些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:CFReadStream
和CFWriteStream
。这两种类型的流均遵循所有常用的Core Foundation API
约定。有关Core Foundation
类型的更多信息,请阅读Core Foundation Design Concepts。
CFStream
建立在CFSocket
之上,是CFHTTP
和CFFTP
的基础。如图1-2所示,尽管CFStream
不是CFNetwork
的正式组成部分,它也是几乎所有CFNetwork
的基础。
您可以像使用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读取流时返回的读取流引用CFReadStreamRef
。 CFReadStreamRead
函数使用FTP服务器的输出填充缓冲区。
有关使用CFFTP
的更多信息,请参阅Working with FTP Servers。
2. CFHTTP API
要发送和接收HTTP消息,请使用CFHTTP API
。就像CFFTP
是FTP
协议的抽象一样,CFHTTP
是HTTP
协议的抽象。
超文本传输协议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请求发送到没有凭据的身份验证服务器(或凭据不正确),则服务器会返回授权质询(通常称为401
或407
响应)。 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与IPv4
和IPv6
兼容。 使用CFHost,您可以编写完全透明地处理IPv4和IPv6的代码。
CFHost与CFNetwork的其他部分紧密结合。 例如,有一个名为CFStreamCreatePairWithSocketToCFHost
的CFStream
函数,它将直接从CFHost
对象创建一个CFStream对象。 有关CFHost对象函数的更多信息,请参阅CFHost Reference
。
5. CFNetServices API
如果您希望应用程序使用Bonjour
注册服务或发现服务,请使用CFNetServices API
。 Bonjour是Apple实施的零配置网络(ZEROCONF)
,它允许您发布,发现和解析网络服务。
为了实现Bonjour
,CFNetServices API
定义了三种对象类型:CFNetService
,CFNetServiceBrowser
和CFNetServiceMonitor
。 CFNetService
对象表示单个网络服务,如打印机或文件服务器。它包含另一台计算机解析该服务器所需的所有信息,例如名称,类型,域和端口号。 CFNetServiceBrowser
是用于发现域内的域和网络服务的对象。 CFNetServiceMonitor
对象用于监视CFNetService
对象的更改,例如iChat
中的状态消息。
有关Bonjour
的完整描述,请参阅Bonjour Overview。有关使用CFNetServices
和实现Bonjour
的更多信息,请参阅 NSNetServices and CFNetServices Programming Guide。
6. CFNetDiagnostics API
连接到网络的应用程序取决于稳定的连接。 如果网络出现故障,这会导致应用程序出现问题。 通过采用CFNetDiagnostics API
,用户可以自我诊断网络问题,例如:
- 物理连接失败(例如,电缆被拔出)
- 网络故障(例如,
DNS
或DHCP
服务器不再响应) - 配置失败(例如,代理配置不正确)
一旦诊断出网络故障,CFNetDiagnostics
将指导用户解决问题。 如果Safari
无法连接到网站,您可能已经看到CFNetDiagnostics
正在运行。 CFNetDiagnostics
助手可以在图1-3中看到。
通过为网络故障的上下文提供CFNetDiagnostics
,您可以调用CFNetDiagnosticDiagnoseProblemInteractively
函数来引导用户完成提示以找到解决方案。 此外,您可以使用CFNetDiagnostics
查询连接状态并向用户提供统一的错误消息。
要了解如何将CFNetDiagnotics
集成到您的应用程序中,请阅读Using Network Diagnostics。 CFNetDiagnostics
是OS X v10.4
中的一个新API。
后记
本篇主要讲述了CFNetwork的一些概念,感兴趣的给个赞或者关注~~~