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所示。

CFNetwork框架详细解析(三) —— CFNetwork编程指导之CFNetwork概念(二)_第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的基础。

CFNetwork框架详细解析(三) —— CFNetwork编程指导之CFNetwork概念(二)_第2张图片
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中看到。

CFNetwork框架详细解析(三) —— CFNetwork编程指导之CFNetwork概念(二)_第3张图片
Figure 1-3 Network diagnostics assistant

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

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

后记

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

CFNetwork框架详细解析(三) —— CFNetwork编程指导之CFNetwork概念(二)_第4张图片

你可能感兴趣的:(CFNetwork框架详细解析(三) —— CFNetwork编程指导之CFNetwork概念(二))