使用Socket和Socket流 <- 网络概述
2017-07-05 本文已影响81人
raingu24
本章描述了建立socket连接的方式,这种连接完全由你的程序控制。大多数程序通过高级API就可以得到很好的实现,例如在前面章节介绍的NSURLConnection。只有你需要支持的协议不是Cocoa或者Core Foundation内置功能支持的协议时候,这些API才可以被使用。
选择socket API
在几乎所有级别的网络中,软件可以被分成两个类别:客户端(连接到其他应用的程序)和服务器端(其他应用连接到的程序)。在高级别上,这些划分是很清晰的。使用高级API写的程序都是纯客户端。但是在低级别上,划分往往是模糊的。
Socket和流编程通常属于下面几个大类之一:
- 基于数据包的通信——一次操作一个数据的程序,监听传入的数据包,然后发送一个响应数据包。使用基于数据包的通信,客户端和服务器端的唯一区别是每个程序发送和接收的数据包的内容,以及(可能)每个程序对数据的使用。网络代码本身是相同的。
- 基于流的客户端——使用TCP发送和接收数据是作为两个方向上的连续字节流的程序,每个方向一个。使用基于流的通信,客户端和服务器端有所不同。客户端和服务器端真实处理数据的部分是类似的,但是程序初始构建通信通道的方式非常不同。
选择基于socket连接的API,取决于你是连接到一台主机,还是从另一台主机接收连接。它还取决于你是使用TCP还是其他协议。这里有几个因素需要考虑:
- 在iOS中,如果你已经有可以共享的非苹果平台的网络代码,你可以使用POSIX C网络API,并继续使用你的网络代码(在单独的线程上)。如果你的应用是基于Core Foundation 或Cocoa(Foundation)的运行循环,你还可以使用Core Foundation CFStream API来把POSIX网络代码集成到主线程的整体架构中。或者,如果你使用GCD,你可以添加一个socket作为派遣资源。在iOS中,POSIX网络是不鼓励的,因为它在蜂窝网络或VPN中是不运行的。因此,作为一般规则,你应该把网络代码从常用数据处理功能中分离出来,并且使用高级API来编写网络代码。
注意:如果你使用POSIX网络代码,你应该意识到POSIX网络API不是协议无关的(protocol-agnostic)(你必须自己处理IPv4和IPv6之间的差别)。它是一个通过IP连接的API,而不是一个名字连接的API,这意味着,如果你想实现和高级API那样的功能,你需要做很多额外的工作。在你决定重用现有的POSIX网络代码之前,务必阅读Avoiding Common Networking Mistakes中的 Avoid Resolving DNS Names Before Connecting to a Host。
- 对于监听端口的守护程序(daemons)和服务器,或者对于非TCP连接,使用POSIX或Core Foundation(CFSocket)C网络API。
- 对于OC中的客户端代码,使用Foundation OC网络API。Fondation定义了高级类来管理URL连接、socket流、网络服务、以及其他网络任务。它还是iOS 和 OS X中主要的非UI的OC框架,为运行循环、字符串处理、集合对象、文件访问等等,提供了例程。
- 对于C的客户端代码,使用Core Foundation的C网络API——是CFNetwork框架的一部分。Core Foundation框架和CFNetwork 框架是OS X和iOS中主要的两种C语言框架。它们一起定义了构建Foundation网络类的功能和结构。注意:在旧版本的OS X中,CFNetwork是Core Services框架的子框架。