关于网络 <- 网络概述
网络的世界是复杂的。用户可以使用多种技术连接到互联网。这些技术包括电缆调制解调器(cable modems)、DSL、Wi-Fi、蜂窝连接(cellular connections)、卫星连接(satellite uplinks)、以太网(Ethernet)、甚至传统的声学调制解调器(acoustic modems)。每个技术都有不同的特性,包括不同的带宽、延迟、丢包、以及可靠性。
../art/AboutNetworking.png用户和互联网的连接方式并不是全部,这进一步增加了复杂性。在用户到互联网服务器的通路上,用户的网络数据会经过一个或者数十个物理连接起来的路径,它们可能是高速的OC-768线(每秒大约400亿比特),可能是贫乏的300波特调制解调器(每秒300比特)、或者任何其他在此之间的性能网络。更糟糕的是,用户连接到服务器的速度在任何时候都可能急剧变化——有人打开了微波炉会影响到用户的Wi-Fi通信、用户可以走出或者驶出蜂窝范围、当你尝试访问的时候有些人可能在地球的另一端开始从服务器下载一个很大的电影,等等。
作为一个网络软件开发者,你的代码必须能够适应网络条件的变化,包括性能、可用性、以及可靠性。这个文档就是告诉你如何做到。
浏览
网络本质上是不可靠的——蜂窝网络更是如此。因此,好的网络代码往往有些复杂。除此之外,你的软件应该:
- 仅传输完成任务所需的数据量。最小化发送和接收的数据量可以延长电池寿命,并可能减少用户的网络使用费。
- 尽可能避免超时。你也许不想让网页停止加载仅仅是因为这个过程花的时间有点长。相反,可以提供一种方式让用户来取消操作。在少数情况下,如果延迟严重,数据将变得没有意义。这时候,不重传数据包的协议或许更有用。例如,如果你正在写一个实时多人游戏,它发送少量的状态信息到另一个在局域网(local area network,LAN)或蓝牙中的设备,通常错过一个信息并且对其他设备上发生的事情进行假设,要好于允许操作系统对这些数据包进行排列并全部发送。但是,对于大多数目的而言,除非你必须保持和已有协议的兼容,否则你通常使用TCP。
- 设计用户界面让用户可以轻松取消长时间没有完成的数据处理。如果应用执行下载一个潜在的大文件,你也应该提供一种方式来暂停这些下载,并在之后恢复它们。
- 优雅的处理失败。连接失败的原因有很多——网络不可用、主机名解析不成功等等。当错误发生时,你的应用程序应该可以在离线状态下继续运行。更复杂的情况是,有些时候用户可能只有在某些网络上才可以访问资源。例如,AirPlay只能在Apple TV处于同一个网络的情况下才能连接。企业网络资源只能在工作或者通过虚拟专用网络(virtual private network,VPN)才可以访问。可视语音信箱只有通过蜂窝运营商(取决于运营商)的网络才可以访问。等等。
- 当网络性能变慢时可以优雅的处理。因为用户的设备和它的ISP之间的带宽是受限的,所以应用在连接家庭网络中的其他设备的速度,要比连接世界另一边的服务器的速度要快得多。如果有人在本地网络使用有限的带宽做其他目的的事情时,这中差异会更加明显。
- 选择合适任务的API。如果有满足你需求的高级别API,那就它来替代低级别的API实现。如果有专门针对你正在做的事情的API(例如游戏中的API),那就使用它。通过使用最高级别的API,你将向操作系统提供更多关于你正在做的事情的目的的信息,以便系统可以对你的请求作出最优的处理。这些高级API也可以为你解决很多复杂的以及困难的网络问题——例如缓存、代理、从主机的多个IP地址中进行选择,等等。如果你写了自己的低级别代码来实现相同的任务,你就必须要自己处理这些复杂的问题(并且调试和维护相关的代码)。
- 谨慎的设计你的软件来最小化安全风险。利用安全技术,例如SSL(Secure Sockets Layer,安全套接字层)以及TLS(Transport Layer Security,传输层安全)来防止欺骗以及隐藏会被窥探的敏感数据,并且仔细检查不受信任的内容来保护缓冲区以及整数溢出。
本文档将会帮助你学习这些概念,以及更多东西。
了解为什么网络很难
虽然编写网络代码可以很容易,对于最简单的网络需求来说就是如此,但编写好的网络代码并非如此。基于你软件的需求,它需要适应网络性能的改变、网络连接失败、连接错误、以及其他因网络自身不可靠造成的问题。
相关章节:Designing for Real-World Networks
OS X和iOS在多个层级上都提供了API
你可以在OS X和iOS中使用相同或相近的代码来完成下面的网络任务:
- 执行HTTP/HTTPS请求,例如GET和POST请求
- 建立与远程主机的连接,可以使用加密或者认证
- 监听传入的连接
- 使用无连接协议发送及接收数据
- 使用Bonjour来发布、浏览、以及解析网络服务
相关章节:
Assessing Your Networking Needs
Discovering and Advertising Network Services
Making HTTP and HTTPS Requests
Using Sockets and Socket Streams
安全通信是你的责任
网络安全是必需的。你应该将所有用户发送的数据当做是机密的,并进行相应的保护。特别是,你应该在传输期间对它进行加密,以防止发送给错误的人或服务器。
为了此目的,大多数OS X和iOS网络API集成了TLS。TLS是SSL技术的继任者。除了在传输中加密数据外,TLS还使用证书来验证服务器以防止欺骗。
你的服务器也应该采取措施来验证客户端。根据需要,该验证可能和密码验证一样简单,或者可以像硬件验证令牌一样复杂。
警惕所有传入的数据。任何从不信任的源接收到的信息,都可能是恶意的攻击。应用应该谨慎的检查传入的数据,并立即丢弃可疑的东西。
相关章节:
Using Networking Securely
iOS和OS X提供的特定平台功能
在OS X上的网络环境是高配置和高扩展性的。System Configuration(系统配置)框架提供用来检查和设置当前网络配置的API。另外,网络内核扩展允许你通过添加功能(例如防火墙或VPN)来扩展OS X的核心网络基础架构。
在iOS上,你能使用特定平台网络API来处理捕获的网络的身份验证,以及指定(designate)VoIP网络流
相关章节:
iOS Requires You to Handle Backgrounding and Specify Cellular Usage Policies
OS X Lets You Make Systemwide Changes
网络必须是动态的、异步的
设备的网络环境在任何时刻都可以改变。有很多简单的(但具有破坏性的)网络错误能对应用的性能和可用性造成不利的影响。例如在主线程上执行同步的网络代码,无法处理正常的网络更改,等等。你可以尽量的在设计的时候多花费一些时间和精力,以便从一开始就避免这些问题,而不是把时间精力花费在事后调试上。
相关章节:
Avoiding Common Networking Mistakes
如何使用本文档
本文档应该顺序阅读。
第一章,Designing for Real-World Networks,解释了你在编写使用网络的软件的时候要面对的挑战,为什么延时很重要,以及其他你在编写第一行网络代码之前应该知道的概念。
接下来的一章,Assessing Your Networking Needs,提供了关于如何选择API家族,以及确定应用将要执行的网络任务是什么类型的更多细节。该章还会让你去看其他的章节(Discovering and Advertising Network Services, Making HTTP and HTTPS Requests, 和 Using Sockets and Socket Streams),这些章节描述了一些你的程序可能需要的常用网络任务。
Using Networking Securely 和 Avoiding Common Networking Mistakes提供能帮助你防止常见网络错误的指导。
最后,Supporting IPv6 DNS64/NAT64 Networks解释了如何确保应用兼容IPv6网络。
还可以看
本文档是OS X和iOS网络连接的高级概述。以下文档提供了更有深度和广度的介绍。
了解底层发生了什么
对网络工作方式的基本了解,可以帮助你理解为什么它可以做到这些行为。因此,你在开始写第一行代码前应该至少了解基本的底层概念。至少,你应该了解数据包和封装、基于连接 vs 无连接协议、子网与路由、域名查找、带宽和延迟。要了解这些主题,阅读下面这个文档:
- Networking Concepts
了解具体技术
想要了解更多深入的信息,可以查阅下面针对特定主题的主要文档指南:
- URL Session Programming Guide
- Stream Programming Guide
- CFNetwork Programming Guide
- NSNetServices and CFNetServices Programming Guide
了解如何在OS X和iOS之间共享文档
下面的文档描述了在OS X和iOS之间共享文档的技术:
- iCloud Design Guide
- Document Transfer Strategies