1.网络模型
1.1 OSI 七层模型
某一层的服务就是该层及其下各层的一种能力,它通过接口提供给更高一层。
(关于七层模型的最佳介绍:OSI 七层模型与 TCP/IP 五层模型,其中将整个过程类比为A公司向B公司发送一份商业报价单的过程相当经典)
1.2 TCP/IP 五层模型
1.3 各级网络层对应的服务
2.http/TCP/UDP
2.1 http
即超文本传输协议。http连接最显著的特点是客户端发送的请求每次都需要服务器响应。在请求结束后会主动释放连接,从建立连接到关闭连接的过程称为“一次连接”。
http1.0:客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。
http1.1:
a.引入了更多的缓存控制策略
b.允许只请求资源的某一部分,可充分利用带宽
c.新增了24个错误状态响应码,更方便开发者的控制
d.支持长连接和请求的流水线处理。在一个连接上可以传送多个http请求和响应,减少了建立和销毁连接的开销。默认开启Connection:keep-alive。
http2.0:基于谷歌的SPDY,传输性能上得到了大大的提升。
a.协议解析基于二进制,之前的都是基于文本。解析更方便更健壮。
b.多路复用:提高带宽利用率,降低延迟。 在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY允许给每个request设置优先级,这样重要的请求就会优先得到响应。
c.header压缩和缓存:使用encoder压缩来减小header的体积,另外双方各自缓存一份header fields表,避免了重复的header的发送
d.服务端推送:不需要每次都发请求。
(http1.0,1.2,2.0 的区别:http1.0 1.2 2.0 的区别)
2.2 TCP
面向连接,传输可靠,但速度较慢,建立连接需要较多开销。
TCP的三次握手:
(1).客户端向服务端发送SYN(1)+Seq(X)
(2).服务端发送 SYN(1) + Seq(Y) + ACK(X+1)
(3).客户端发送 Seq(Z) + ACK(Y+1)
TCP的四次挥手
(1).第一次挥手,客户端发送一条FIN信息给服务端,然后服务端进入等待状态
(2).第二次挥手,服务端收到FIN信号后,发送一条ACK信号给客户端。并关闭连接。
(3).第三次挥手,服务端等关闭连接后,再发送一条FIN信息给客户端。
(4).第四次挥手,客户端收到FIN信号后,关闭连接,并发送ACK给服务器。
2.3 UDP
面向非连接,传输不可靠,但速度快。
3.短连接与长连接
短连接:连接->传输数据->关闭连接。一般web网站的http请求都用短连接,减小服务端的资源占用。(http1.1及2.0也支持长连接)。
长连接:连接->传输数据->传输数据。。。->传输数据->关闭连接,安全性较差。一般用于操作频繁的点对点通讯。
4.HTTPS
如上图所示,https比http多了一层SSL/TLS,而多出来的这一层就是用来给传输内容加密的。https协议需要申请CA证书。可以有效的防止运营商劫持。
https 如何保证传输安全:首先是有个CA证书的身份认证。其次客户端第一次向服务端请求时,服务端会返回一个带公钥的隐私空间,客户端之后就用拿到的公钥将自己要发送的数据加密后发送给服务端,服务端收到数据后再拿自己保存的私钥来对数据进行解密。
5.socket
socket ,又称套接字,本身并不是协议,它是对TCP/IP协议(包含传输层的TCP UDP 协议以及网络层的IP协议等,统称TCP/IP协议)的封装,基于TCP UDP协议之上,其实就是一个对外的接口。我们通过socket 接口可以方便的进行网络编程,而不用直接面对底层的TCP/IP协议。建立socket通讯至少需要两端:ClientSocket和ServerSocket,建立连接的过程可以总结为:服务端监听,客户端请求,确认建立连接。
6.网络缓存
6.1 GET网络请求的缓存
首先明确,post请求是无法缓存的,只有get请求可以缓存,因为get请求是幂等的。
其次,设置网络请求的缓存只需要两行代码即可搞定,如下所示:
NSURLCache *urlCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:urlCache];
6.2 控制缓存的有效性
如上的两行代码的确可以控制缓存的有效期,但是这样的方式不够灵活。当有个需求要求服务器数据一旦更新,我们的请求就必须刷新的时候,以上的方式就不满足需求了。解决这个问题的思路就是:对比客户端本地和服务器端是否一致,不一致的时候才返回数据。
Etag:基于hash,是强校验,官方推荐的方式,但需要服务端支持。我们根据服务端的响应码来判断是使用本地缓存还是使用新的请求到的数据。比如,当收到响应码为304时,此时data会是空的,表示服务端数据没有更新,我们继续使用本地缓存数据,当收到的响应码为200时,表示data有值,我们需要使用新的数据。
Last-Modified:基于时间戳,是弱校验,一般服务端都会支持。
当然,这个只是标准协议中给我们提供的校验方式,你也完全可以和服务端自己协商确定其他的校验方式。
7. 文件上传 下载 断点续传
由于NSURLConnection已经弃用,所以我们现在只需要了解NSURLSession的方式了。
核心思想:将网络请求进行封装,实现多线程。例如将一个网络请求的任务进行包装,生成一个NSURLSession,NSURLSession会自动实现多线程,它的回调block就是在子线程中。然后可以通过代理监听这个过程(进度,是否成功等)。
NSURLSession的使用步骤:(1).创建对应的task对象 (2).执行task
文件下载:
(1).NSURLSessionDownloadTask:专门下载用的task,配合它的代理可以更方便的实现断点下载功能,但也有一个缺陷,就是我们获取不到下载中间过程的数据,也就是这些数据是存在内存中的,当我们在下载过程中关闭程序,这些数据也就丢失了,所有的数据都需要重新下载。
(2).NSURLSessionDataTask:我们可以获取下载的数据流,从而存储到沙盒中,关闭程序再进入我们依然可以从沙盒中读取之前下载的数据,实现离线断点下载功能。
文件上传:NSURLSessionUploadTask
注意:及时释放 session
8.网络监测和网络检测
网络监测:属于被动响应,当网络状态有变化时,能自动触发相应的方法或通知。可以实现的工具有AFN和Reachability。
网络检测:主动检测网络的情况,分析网络连接的情况,基本在APP的网络诊断功能中会用到。有个比较好的第三方推荐下:LDNetDiagnoService_IOS,这里面基本的ping,域名解析,traceroute的功能都有了。
9.网络安全
(1). 网络传输时不允许用明文传输敏感信息,敏感数据需加密(base64,对称加密,非对称加密)
(2). 使用https,并且使用证书验证的方式发送请求。
(3).数据传输完整性校验:MD5摘要算法
10.网络优化:
(1).如果可以,使用http2.0会明显减小网络延迟(header压缩和缓存,服务器推送减少请求,多路复用及请求的优先级设置)
(2).合理使用网络缓存,减少不必要的网络请求,提高加载速度也节约了流量
(3).使用高效的数据交换格式,一般来说Json比XML要更高效,而PB又优于Json。不过鉴于使用的方便性,所以更多的开发者都选择使用Json.
(4).资源优化:尽可能的缩小传输数据,比如尽量使用webp代替PNG和JPG,因为同样的图片它的体积更小。
参考:
https://www.jianshu.com/p/a470ab485e39
https://www.cnblogs.com/qishui/p/5428938.html
https://www.jianshu.com/p/78964aac72d5
https://www.cnblogs.com/ziyi--caolu/p/8058577.html