POST请求不能被缓存,只有 GET 请求能被缓存。因为从数学的角度来讲,GET 的结果是幂等的,就好像字典里的 key 与 value 就是幂等的,而 POST 不是幂等 。缓存的思路就是将查询的参数组成的值作为 key ,对应结果作为 value。
设置缓存步骤:
NSURLCache *urlCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:urlCache];
控制缓存的有效性:
Last-Modified
: 是资源最后修改的时间戳,往往与缓存时间进行对比来判断缓存是否过期。
具体分析: 在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,格式类似这样:Last-Modified: Fri, 12 May 2006 18:53:33 GMT
。
客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头,询问该时间之后文件是否有被修改过: If-Modified-Since: Fri, 12 May 2006 18:53:33 GMT
。
如果服务器端的资源没有变化,则自动返回 HTTP 304 (Not Changed.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。
HTTP 协议规格说明定义ETag为“被请求变量的实体值”。 另一种说法是,ETag是一个可以与Web资源关联的记号(token)。它是一个 hash 值,用作 Request 缓存请求头,每一个资源文件都对应一个唯一的 ETag 值。
通过 ETag
和 If-None-Match
判断本地缓存数据是否发生变化。如果ETag没改变,则返回状态304不返回,和Last-Modified
一样。
ETag
是的功能与 Last-Modified
类似:服务端不会每次都会返回文件资源。客户端每次向服务端发送上次服务器返回的 ETag 值,服务器会根据客户端与服务端的 ETag 值是否相等,来决定是否返回 data,同时总是返回对应的 HTTP 状态码。客户端通过 HTTP 状态码来决定是否使用缓存。比如:服务端与客户端的 ETag 值相等,则 HTTP 状态码为 304,不返回 data。服务端文件一旦修改,服务端与客户端的 ETag 值不等,并且状态值会变为200,同时返回 data。
因为修改资源文件后该值会立即变更。这也决定了 ETag 在断点下载时非常有用。
在官方给出的文档中提出 ETag 是首选的方式,优于 Last-Modified 方式。因为 ETag 是基于 hash ,hash 的规则可以自己设置,而且是基于一致性,是“强校验”。 Last-Modified 是基于时间,是弱校验,弱在哪里?比如说:如果服务端的资源回滚客户端的 Last-Modified 反而会比服务端还要新。
虽然 ETag 优于 Last-Modified ,但并非所有服务端都会支持,而 Last-Modified 则一般都会有该字段。大多数情况下需要与服务端进行协调支持 ETag ,如果协商无果就只能退而求其次。
运营商DNS劫持和故障实例图:
App内用域名发送请求都要经过DNS解析出ip,然后再根据ip去拿对应的资源,这个过程中,如果LocalDNS中存在这个域名对应的ip,就会直接返回这个ip,类似于App内做缓存。如果不存在,才会去权威DNS查询改访问哪个ip,然后查询到的ip会在LocalDNS中做缓存。
HTTPDNS的实现,根据各自团队的情况可以选择自建或者第三方SDK的方案。根据目前DNS劫持和故障的严重程度,以及实现方案的成本对比。
HTTPDNS集成整体简图:
接口层主要为了对外提供简洁的接口,降低使用者的接入成本,提高开发效率,如接口层提供的部分接口如下:
/// 开启HTTPDNS服务
- (void)startHTTPDNS;
/// 白名单列表,如果设置了白名单,则只有在白名单内域名走httpdns服务
@property (nonatomic, copy) NSArray *whiteDomainList;
/// 黑名单列表,如果设置了黑名单,黑名单内域名都不走httpdns,黑名单的优先级最高
@property (nonatomic, copy) NSArray *blackDomainList;
/// 是否允许缓存ip,允许缓存的情况下,在通过第三方服务无法获取ip的情况下,允许使用上次解析成功的ip进行请求,默认YES
@property (nonatomic, assign) BOOL enableCachedIP;
最佳实践小结
因此,如果你对性能有这很高的要求,同时又需要处理SNI场景的问题,我建议不要直接主动使用HTTPDNS,而是在运营商LocalDNS获取的IP请求失败的情况下,可以在底层直接使用基于CFNetwork的网络请求进行重试,这样就能在请求DNS劫持和性能中间得到一个平衡,既能保证在运营商的LocalDNS解析出现问题时能够走HTTPDNS,保证成功率和可用性;同时又能够在运营商的LocalDNS可用时,使用基于NSURLSession的请求,享受系统实现的HTTP2.0特性带来的性能提升。
备选LocalDNS原因
如果之前访问api.weibo.cn的是联通用户,现在新用户使用电信来访问api.weibo.cn,由于localDNS缓存的存在,不会去查询新浪的权威DNS,这样返回的ip是联通这个运营商的ip,从而会使得用户出现访问变慢等状况。缓存还会导致一点就是,当权威DNS将域名与ip的映射发生改变之后,由于LocalDNS缓存没有及时改变,用户就会访问到错误的服务器,或者直接访问不到资源。
HttpDNS部署等有难度,替代方案:APP内置severs IP list,ping出最合适的Sever address。省去DNS查询时间。
和后台确定一些错误码,根据错误码类型判断是否需要重发会比较合理。一般3次的重试基本可以排除网络抖动的情况。三次失败之后即可认为请求失败。
对于百分百送达服务器的请求,第一步并不是直接发送,而是存入本地数据库中,这样即使杀掉进程、断电、重启等极端操作,请求数据也依旧存在,我们可以在App重启或者进入该业务界面时,还原请求数据到内存中,重新进行发送。
使用一定的节流策略,如延迟请求、取消当前请求、取消所有请求等
www.52im.net/thread-2479…
资源优化基本就是尽可能的缩小传输数据的大小,首先是图片大小的解决方案。
方案: 在一定程度上使用webp来代替jpg、png图片
需要注意的是,webp的图片要通过解析才能成为可用的jpg图片,在iOS开发中,可以使用SDWebImage框架进行解析,webp->NSData->Image,app内解析是肯定需要花费一定时间和性能的。 在wifi条件下,超过300300的图片使用webp图片,解析时间+下载时间是比直接使用jpg\png图片要快的,并且在流量方面也是消耗很小。低于300300的可以直接下载使用jpg\png图片。在4G条件下,用户可能会对流量比较敏感,建议都走webp图片。
HTTPS 是在 HTTP 基础上增加了 SSL 层,传递加密的内容,比较安全。
对称加密: 采用单钥加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密。由于其速度快,对称性加密通常在消息发送方需要加密大量数据时使用。
非对称加密算法需要两个密钥:公钥和私钥。如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
二进制分帧 首部压缩 多路复用 服务器推送 请求优先级
HTTP/2 主要是 HTTP/1.x 在底层传输机制上的完全重构,相比 HTTP/1.x,HTTP/2 在底层传输做了很大的改动和优化:
HTTP,超文本传输协议。是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式。由于其简捷、快速的方式,适用于分布式超媒体信息系统,是现今在WWW上应用最多的协议。
我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,比如HTTP、FTP、TELNET等,也可以自己定义应用层协议。WEB使用HTTP协议作应用层协议,以封装HTTP文本三/IP做传输层协议将它发到网络上。
HTTP 的全称是 Hypertext Transfer Protocol,超文本传输协议。
规定客户端和服务器之间的数据传输格式。
让客户端和服务器能有效地进行数据沟通。
发送HTTP请求的方法在HTTP/1.1协议中,定义了8种发送http请求的方法 :GET、POST、PUT、DELETE、HEAD、OPTIONS、TRACE、CONNECT、PATCH。
GET /home.html HTTP/1.1 Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br Referer: https://developer.mozilla.org/testpage.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT
If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a"
Cache-Control: max-age=0
Access-Control-Allow-Origin: *
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Mon, 18 Jul 2016 16:06:00 GMT
Etag: "c561c68d0ba92bbeb8b0f612a9199f722e3a621a"
Keep-Alive: timeout=5, max=997
Last-Modified: Mon, 18 Jul 2016 02:36:04 GMT
Server: Apache
Set-Cookie: mykey=myvalue; expires=Mon, 17-Jul-2017 16:06:00 GMT; Max-Age=31449600; Path=/; secure
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
x-frame-options: DENY
200:请求成功。
400:客户端请求语法的错误,服务器无法解析。
404:服务器无法通过客户端的请求找到资源。
500:服务器内部错误无法完成请求。
三次握手目的是确认双方的接收与发送能力是否正常。
理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次挥手”。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。
但其实第三次握手的时候,是可以携带数据的,第一次、第二次握手不可以携带数据。
假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。
1.客户端发送一个 FIN 报文(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。
2.服务端收到 FIN,发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。
3.如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态,即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。
4.客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,关闭连接,处于 CLOSED 状态。
TCP:传输控制协议。
是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议。
TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
UDP:用户数据包协议。
是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。
UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。
面向连接:是指通信双方在通信时,要事先建立一条通信线路,其有三个过程:建立连接、使用连接和释放连接。电话系统是一个面向连接的模式,拨号、通话、挂机;TCP协议就是一种面向连接的协议。
面向无连接:是指通信双方不需要事先建立一条通信线路,而是把每个带有目的地址的包(报文分组)送到线路上,由系统自主选定路线进行传输。邮政系统是一个无连接的模式,天罗地网式的选择路线,天女散花式的传播形式;IP、UDP协议就是一种无连接协议。
都是通信协议,也就是通信时所遵守的规则,只有双方按照这个规则“说话”,对方才能理解或为之服务。
HTTP 本身就是一个协议,是从Web服务器传输超文本到本地浏览器的传送协议。HTTP协议是基于TCP连接的。主要解决如何包装数据。
TCP/IP 是个协议组,分为四个层次:网络接口层、网络层、传输层和应用层。主要解决数据如何在网络中传输。
网络层:IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。
传输层:TCP协议与UDP协议。
应用层:FTP、HTTP、TELNET、SMTP、DNS等协议。
网页(网址以http://开头)都是 http 协议传输到你的浏览器的,而 http 是基于 socket 之上的。socket 是一套完成 tcp,udp 协议的接口。
TCP和UDP协议属于传输层 。而http是个应用层的协议
Socket 是对 TCP/IP 协议的封装,Socket 本身并不是协议,而是一个调用接口(API),通过 Socket,我们才能使用 TCP/IP 协议。Socket 的出现只是使得程序员更方便地使用 TCP/IP 协议栈而已,是对 TCP/IP 协议的抽象,从而形成了我们知道的一些最基本的函数接口。
http 连接:http连接就是所谓的短连接,即客户端向服务器端发送一次请求,服务器端响应后连接即会断掉;
socket连接:socket连接就是所谓的长连接,理论上客户端和服务器端一旦建立起连接将不会主动断掉;但是由于各种环境因素可能会断开,比如:服务器或客户端主机 down 了,网络故障,或者两者之间长时间没有数据传输,网络防火墙可能会断开该连接以释放网络资源。所以当一个 socket 连接中没有数据的传输,那么为了维持连接需要发送心跳消息,具体心跳消息格式是开发者自己定义的。
建立Socket连接至少需要一对套接字,一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket。
套接字之间的连接过程分为三个步骤:
Cocoa 层:
NSURL,Bonjour,Game Kit,WebKi。这层是最上层的基于 Objective-C 的 API,比如 URL 访问,NSStream,Bonjour,GameKit等,这是大多数情况下我们常用的 API。Cocoa 层是基于 Core Foundation 实现的。(可触摸层)。Core Foundation 层:
基于 C 的 CFNetwork 和 CFNetServices。因为直接使用 socket 需要更多的编程工作,所以苹果对 OS 层的 socket 进行简单的封装以简化编程任务。该层提供了 CFNetwork 和 CFNetServices,其中 CFNetwork 又是基于 CFStream 和 CFSocket。(核心服务层)。OS 层:
基于 C 的 BSD socket。(核心操作系统层)
加密对象:隐私数据,比如密码、银行信息 加密方案:
1.提交隐私数据,必须用POST请求
2.使用加密算法对隐私数据进行加密,比如MD5
3.加密增强:为了加大破解的难度 对明文进行2次MD5 : MD5(MD5(
4.BASE 64:是网络传输中最常用的编码格式,用来将二进制的数据编码成字符串的编码方式。
加密对象:重要的数据,比如游戏数据
现在已经有工具和技术能反编译出源代码:逆向工程
解决方案:发布之前对代码进行混淆
@interface HMPerson :NSObject
- (void)run;
- (void)eat;
@end
@interface A :NSObject
- (void)a;
- (void)b;
@end
zipFile :需要解压的zip文件的路径 dest : 解压到什么地方 [SSZipArchive unzipFileAtPath:zipFile toDestination:dest];
阅读量:537
点赞量:0
收藏量:0