Network Summary
目录:
- 常见的客户端请求流程
- 如何优化网络请求
- 扩展一:Https
- 扩展二:AFNetworking
常见的客户端请求流程
自己整理了一下,画了一张流程图,常规的基于 TCP/IP 的请求流程。

如何优化网络请求
1. 客户端发起请求
这个在 iOS 端一般都是借助第三方网络库,创建好参数然后发起请求。当然用系统原生的也完全 ok,毕竟第三方库也只是对系统网络请求的一个比较好(非常好)的封装。这里是客户端可控区域,再往下就很难控制了。优化的点有
- 参数配置
比如NSURLSession里有一个属性/* Allow the use of HTTP pipelining */ @property BOOL HTTPShouldUsePipelining;设置这个属性可以开启
请求管道,原理和优缺点会在下文叙述。 - 压缩报文
加快请求报文的传输。
2. DNS 查询
一般请求会向域名发起而不会直接通往目标 ip 地址,这个时候就需要做 DNS 查询,简单的说就是通过域名查询到目标服务器的 ip 地址。这个点至少有两个地方可以优化。
- 查询速度。一般 DNS 都有缓存,也会设一个缓存过期时间,这就导致了查询时间的不稳定。
- DNS 劫持。经常有运营商劫持 DNS,强行扔几个广告给你看。
这里业界一般采用HTTPDNS来优化上述两个方面。查询了一下似乎是要收费的,目前项目中也没有尝试..
3. 3次握手建立连接
第一次建立连接,3次握手必不可少。这里可以优化的点在于,在很多个请求的情况下,如何减少建立连接的时耗.
这里引用一张《HTTP权威指南》中的原图,比较直观。

一般情况下,HTTP/1.1 的持久连接在默认情况下是激活的,除非特别指明,否则 HTTP/1.1假定所有连接都是持久的。
这也就意味着我们一般在客户端发多个请求可以采用第二种方式,不用每次发请求都要进行3次握手了。那么这里还能优化吗? 可以看到,第三种管道化持久连接的方式好像更酷,耗时也比第二种更少。但是这中管道化连接有比较大的限制。
- 需要服务器支持
- 不能(不应该)以管道化方式传送非幂等请求(Post)
- 客户端应该要能确认连接是持久的
- 响应返回的顺序应该跟请求对应起来
- 客户端必须做好连接会随时断开的准备
emmmm… 那么我们还是采用第二种吧。(那特么不是根本没优化吗,我们好像什么都没做啊)
顺带一提,HTTP2.0 有个比较好的机制:多路复用,极大地提高了请求速度。
关于客户端与服务器的长连接,我有一些疑问
- 我们平常写请求代码的时候,是
每次都重新建立连接还是只有第一次建立连接,之后都是在这条持久连接里面? - 客户端与服务器的 TCP 长连接是与
NSURLSession对应还是NSURLSessionTask还是NSURLRequest? - 如何验证客户端的一个请求是否与服务器进行了三次握手?
4. 传送请求报文
这个不太好做优化,毕竟已经是数据链路层和物理层的事情了。这里可以考虑在第二个阶段,返回服务器 ip 地址的时候,返回一个离用户比较近的 ip(大厂专用优化)。
5. 服务器处理
这里就是写后台朋友的优化了。
- 数据查询方向(sql 优化、redis…)
- 数据处理方向(算法优化…) …
6. 返回响应报文
这个同第4点
7. 4次挥手断开连接
这个好像真没法优化
8. 客户端处理数据
这里跟程序员的数据结构、算法水平相关。比如后台返回了一棵比较复杂的树,怎么处理更好?一般情况下只是简单的 Array、Map 应该处理起来问题不大。
9. 刷新 UI
这一点其实跟网络已经没什么关系了,主要是一些空间跟时间的取舍。比如要展示一个新闻列表
- 先不画
UITableView,获取到数据了再实例化UITableView并展示。 - 直接实例化空的
UITableView, 获取到数据后再reloadData。
10. 缓存策略
以上的优化都是基于与服务器交互的前提下,当我们已经请求过某个接口后,再次需要数据的时候,其实可以完全避免上述操作。
那么如何来缓存请求数据呢?我个人是采用了 YYCache 第三方库来实现的。
扩展一:Https
如果简单地理解 Https 的话,就是采用了对称加密和非对称加密的 Http,它比起 Http 多了一层 SSL 安全层。
比起简单的 Http,Https 建立连接时多了 SSL 握手。
SSL 握手后就跟普通的 TCP 连接一样啦,不过每次这样也挺耗时的,Https 也进行了很多优化,比如 session 复用。
btw,以前也写过一篇关于 Https 的博客,那时了解了一下对称加密跟非对称加密,然后记录了下来。觉得了解的应该差不多了,然后有次被别人问起 Https,讲了之后对方还是不停地深入发问,然后就蒙蔽了,所以这次总结网络的时候顺便又去学了一下。
扩展二:AFNetworking
这里提一下 AFNetworking,因为这是iOS最常用的网络库。
核心类:AFURLSessionManager,负责请求的发起、调度、回调。
安全类:AFSecurityPolicy, 负责 HTTPS 验证。
检测类:AFNetworkReachabilityManager, 负责检测客户端网络连接情况。
解析类:AFHTTPRequestSerializer,AFURLResponseSerialization,负责设置请求报文和响应报文。
简单画一下流程图,如有错误请联系我指出,万分感谢。
