iOS http https udp tcp dns cookie/session讲解
http几个请求方式
请求方式:
1. GET
2. POST
3. DELETE
4. PUT
5. HEAD
6. OPTIONS
我们最常用的请求方式就是get和post,那么两者有什么区别呢?
get 请求参数一般以?拼接到 URL 后面,post请求参数放在body体里面
get 参数长度限制2048个字符,post 一般没有限制
get相对post是不安全的
GET 一般是用来获取资源的,是安全的可缓存的幂等的
post 一般是用来处理资源的
安全性:不应该引起server端的任何状态变化,GET HEAD,OPTIONS
幂等性:同一个请求方法执行多次和执行一次效果完全相同,PUT,DELETE,比如get获取一次和N次是一样嗯嗯
可缓存性:请求是否可以被缓存,一般会有代理服务器缓存,多次请求可能获取的是缓存
http常见错误码含义
2xx:一般表示成功
3xx:发生网络重定向
4xx:客户端发生的请求有问题
5xx:server本身有异常
http 特点
- 无连接,建立连接和释放连接,引出http 持久连接
- 无状态,server是不知道是同一个用户的,引出cookie、session
非持久连接:每次都需要建立连接和释放连接,每次都需要三次握手四次挥手
持久连接,在一定时间之内都是用这条通道,一段时间之后关闭这条连接通道,
持久连接头部字段:
connection:keep-alive,采用持久连接
time:20,20s之内不会断开连接,不会进行四次挥手,可以复用。
max :10,这条连接最多可以发起多少请求
怎样判断一个持久连接是否结束?:
content-length:1024,响应报文头部,客户端可以根据接收数据大小是否到达这个大小来判断
chunked:http相应报文,最后会有一个空的chunked
Charles 的抓包原理是什么呢?:
利用http中间人攻击来实现的
正常:client和server直接交互的,中间人攻击,是有个中间人,当我们发起一个请求的时候,会有一个中间人,通过中间人发起请求给server,然后server把数据返回给中间人中间人返回给客户端,这样其实我们的中间人是可以篡改数据的。
三次握手四次挥手
- 客户端发起连接,需要发送 syn 同步报文
- 当server端收到之后,server会返回一个同步ack的,syn同步报文
- 客户端会返回一个确认ack报文,三次握手
- http请求报文
- server 返回http响应报文,请求结束开始四次挥手
- 客户端发送 fin 终止报文,四次挥手开始
- server返回确认ack报文,客户端到server端链接断开
- 客户端到server端的链接断开,但是server到客户端的不一定断开,可能还会传递数据,在某一时机,server像客户端发送fin,ack报文
- 客户端回应确认ack报文,这样就完成了server到客户端的断开,完成了四次挥手
为什么三次握手,不是两次
1.当我们发送的syn超时的情况下,我们的客户端会通过超时重传的逻辑,重新发送一个syn同步报文,这时候server端会返回给客户端一个确认syn,ack同步确认报文,如果只有两次握手,那么连接已经建立,如果这时候我们之前的超时syn报文发送出去了,server端认为,客户端又要建立连接,认为是第二次连接,又返回给客户端一个ack确认报文,其实第一个报文是超时。通过三次握手就可以解决,当我们的超时syn报文发送成功之后,server返回同步确认报文,只收客户端进行第三次握手,返回给server一个ack确认报文,就代表建立了连接,当我们的超时syn报文再次发送给server端的时候虽然server端会返回一个syn同步报文,但是server端发现,一段时间之后,客户端并没有发送ack确认报文,那么请求就没有建立。
所以三次握手解决了这种超时重传的逻辑
为什么四次挥手?进行两次断开
四次挥手是,客户端向server端发送fin终止报文,然后server回复客户端一个确认ack报文,这时候完成了版关闭状态,如果这时候server仍然有数据向客户端发送是可以的,但是翻过来不可以,就需要server断开,server想客户端发送fin终止报文,然后客户端回复ack确认报文。
客户端和server建立的tcp连接为全双工的,互相可以给互相发送,所以就需要双向断开,四次挥手
https
https = http + ssl/tls
那么他的协议栈是什么样子呢?
http SSL/TLS > 应用层,或者说应用层之下,传输层之上
tcp > 传输层
IP > 网络层
https 连接建立流程
首先客户端向server端发送一个报文,包含TLS版本号和所支持的加密算法和一个随机数 C,三个重要信息到server端,当server端收到之后,返回选定的加密算法和server证书和一个随机数S,当客户端收到之后,先验证server证书是否合法,然后通过随机数C,随机数S,和预主秘钥组装一个会话秘钥,然后通过server端的公钥对预主秘钥进行加密传输,server端收到之后,通过私钥解密得到预主秘钥,然后通过随机数C,S,和预主秘钥,组装会话秘钥。
然后客户端向server端发送加密的握手消息,server端向客户端返回加密的握手消息,这样就建立了连接。
会话秘钥:
会话秘钥 = 随机数 S + 随机数 C + 预主秘钥,使用的是对称加密
https 使用了哪些加密手段,原因是什么?
连接过程中使用非对称加密,非对称加密是非常耗时的
后续的通信过程使用的是对称加密
非对称加密:
非对称加密的两个非常重要的概念就是公钥和私钥,加密用公钥,解密用私钥,比如当发送方向接受方发送 hello word ,首先客户端会使用公钥对其进行加密,然后将加密后的内容发送出去,当接收方收到之后,使用私钥进行解密。
对称秘钥:
加密和解密是同一把秘钥,流程一样,对称秘钥在传输过程中,容易被劫持,那样就不安全了,而非对称加密只有公钥传输,私钥是自己保存的,所以相对安全一些。
tcp/udp
udp 用户数据报协议
特点:
1. 无连接:无需建立连接和释放连接
2. 不保证可靠传输,但尽力传输
3. 面向报文,既不合并也不拆分
面向报文:
面向报文的意思是,既不合并也不拆分,意思就是说,
1. 应用层:应用层产生一个报文,这个报文可能很小,也可能很大,当很小的时候,不做合并,很大的时候也不做拆分,而是原封不动的传输。
2. 传输层:当把应用数据报发到传输层之后会将应用层的完整数据当做传输层的数据部分,然后加上UDP头部,发送到网络层
3. 网络层:当收到传输层的数据后,将数据作为IP数据报的数据部分,然后加上IP首部
功能:
1. 复用
2. 分用
3. 差错检测
复用:传输过程中是IP:端口号,复用值得就是多个端口号复用传输层UDP协议然后到IP层,复用
分用:指得是,从IP层收到数据之后,然后传到UDP传输层,然后根据目标端口进行分发,分发到不同的端口。
差错检测:检验和
tcp
特点
1. 面向连接
2. 可靠传输
3. 面向字节流
4. 流量控制
5. 拥塞控制
1.面向连接:
数据传输开始之前要建立连接,也就是三次握手,数据传输结束之后,需要释放连接,也就是四次挥手
2.可靠传输:
1. 无差错
2. 不丢失
3. 不重复
4. 按序到达
可靠传输是通过停止等待协议实现的
1. 无差错情况
2. 超时重传
3. 确认丢失
4. 确认迟到
无差错情况:
客户端发送M1到server,server回复确认M1 ,发送M2 ,M3,server都会回复相应的确认报文
超时重传:
客户端发送M1分组报文,。可能某些原因这个报文被篡改了,那么server端会判定为由差错的报文直接丢弃,或者发送M1超时,server收不到,那么客户端在一定时间内就收不到server端的确认报文,这时候客户端会进行超时重传M1,当server收到之后会返回确认报文。
确认丢失:
当客户端给server端发送M1的时候,server端需要给客户端回确认报文,当这个确认报文丢失的时候,客户端仍然可以通过超时后重传的逻辑,重新发送M1,这时候server会丢弃重传的M1,然后重传给客户端一个确认M1报文
确认迟到:
当客户端想server端发送M1报文的时候,需要server端回确认报文,一段时间 之后,客户端没有收到,会触发超时重传的逻辑,然后server端回丢失这个超时重传的M1,然后重传确认M1报文,但是一段时间之后,前面的server端返回的超时确认M1 报文,送达到了客户端,这时候客户端收到之后,什么事也不做,只是收到了.
3.面向字节流
当我们发送方向接收方发送数据的时候,比如发送方发送了20个字节,那么tcp并不一定是一次性发送者20个字节,可能是先发送10个再发送10个,是有tcp自己决定的。
4.流量控制
滑动窗口协议:
发送窗口:
我们通过应用程序提交给tcp发送缓存中的数据是由字节编号的,从小到大,我们发送的数据都是需要server端确认的,比如我们现在有一块发送缓存,是有字节编号,假如有一小块发送出去了,那么这块已发送出去的缓存的开始位置,就是最后被确认的字节,在已发送的右侧是最后发送的字节,我们的发送窗口要比这个缓存要小一点,比发送的数据要大一点,我们把已发送数据的左侧称为发送窗口的前檐,右侧称之为发送窗口的右檐或者后檐。
我们发送窗口的大小一方面由发送缓存决定,另一方面也是有接收方来确定的,如果我们接收方处理数据能力比较弱或者网络不好,接受速率慢,如果我们发送的快,那么会导致接收方缓存大量缓存甚至溢出,所以接收方也会决定发送方的发送窗口大小,告诉发送方还可以发送多少字节,发送窗口和接受窗口为位于tcp首部的两个字段的,通过调整发送窗口的大小,进而调整发送速率,从而调整流量控制。
接收窗口:
接收方也是有缓存的,我们想向应用程序提交数据的时候,必须是有序的,我们应用程序能读取的字节,就是前面按序到达的数据,对于接收窗口来说,有大小限制的,取决于接受缓存,可以根据接受窗口的大小,通过tcp的首部值,反向制约发送方的发送窗口大小,来保证不溢出,按序到达可以通过字节顺序来控制。
5.拥塞控制
1. 慢开始,拥塞避免
2. 快恢复,快重传
慢开始,拥塞避免:
慢开始:比如一开始我们可以发送一个报文,如果没有拥塞,下次发送两个报文,如果还没有,下次四个,八个,成指数形式增长,也就是慢开始方法。
当增长到我们的窗口值16的时候,会通过拥塞控制的手段,进行增长,比如17,18,呈线性增长,当我们发送的报文数,达到24的时候,可能发送拥塞,比如我们连续三个ack都没有收到,我们就认为网络拥塞了,此时就采用拥塞避免的乘法减小的策略,只发送一个,来减小拥塞,再重新进行慢开始,并把拥塞窗口值,降到一半,比如以前24,现在12,在我们没有达到窗口值得时候采用指数增长,当达到了之后,采用拥塞避免的方法进行加法增大,这个过程就构成了拥塞控制的方案。
快恢复,快重传:
是基于慢开始产生的,当我们达到拥塞窗口阈值之后,回到一个新的阈值,然后进行慢开始,拥塞避免
DNS
DNS 解析其实是域名到IP的映射,DNS 请求采用 UDP 数据报,是明文的
客户端向DNS服务器发送一个请求,然后DNS服务器返回给客户端一堆IP,然后客户端拿着这个IP,向IP服务器发起请求
递归查询:
询问的方式
client-本地DNS-根域DNS-顶级DNS-权威DNS
注意上面是双向的,意思就是说,我们发起一个DNS解析的时候,首先会问本地DNS是否有,如果没有向根域DNS发起请求,如果还没有,向顶级DNS发起请求,如果还没有就去问权威DNS,然后依次回答,一直到客户端。
迭代查询:
原则是谁可能知道。
比如我们客户端发起一个域名解析,客户端向本地DNS发起一个请求,本地DNS去请求顶级DNS,顶级DNS查询不到,然后告诉本地DNS,根域DNS知道,然后本地DNS就像根域DNS发起请求,这时候根域DNS也不知道,就告诉本地DNS,权威DNS知道,然后本地DNS就像权威DNS发起请求,然后权限DNS就告诉本地DNS,本地DNS告诉客户端。
DNS 解析可能出现的问题
1. DNS 劫持
2. DNS 解析转发问题
DNS 劫持:
比如我们客户端向DNS服务器发起一个请求,来获取域名对应的IP,由于我们的DNS解析过程是UDP数据报明文传输,就有可能被窃听,这时候有个钓鱼的DNS服务器,劫持了我们的请求,然后返回给我们一个错误的IP,这时候我们就回去访问一个错误的服务器
DNS 劫持和http有关系吗?他们是没有关系:
DNS 解析是发生在http建立连接之前的
DNS 解析请求使用udp 数据报,访问53端口号
DNS 解析转发
比如我们现在客户端要去解析一个域名,想本地DNS服务器发起请求,我们可能是移动运营商,这时候移动可能会把这个请求转发给电信DNS服务器,然后电信DNS服务器会根据不同的请求解析出不同的IP,此时电信的DNS服务器可能解析出,移动的IP为:2.2.2.2,电信的IP为:3.3.3.3,然后把电信的IP返回回去了,这时候我们客户端连接的就是电信运营商,会出现跨运营商访问的问题,就会出现连接缓慢等问题.
怎样解决 DNS 劫持
1. HTTPDNS
2. 长连接
DNS 解析两种方式第一种是通过DNS协议想DNS服务器发起53端口的请求,而HTTPDNS是通过http协议向DNS服务器的80协议进行请求
解决方案:
我们的HTTPDNS解析是通过IP直连的方式进行的,http://119.29.29.29/dn=xxx.xxx.xxx,&ip=,这是一个狠强大的DNSserver,当我们请求了这个服务器之后,会返回给我们响应的IP地址,然后我们访问就可以了。
长连接方案:
为了避免公网DNS劫持的问题,我们可以和在和我们的APIserver进行交互的时候,在中间和一个长连server进行交互,我们和长连server进行一个tcp长连通道,然后通过长连server通过内网专线,向我们的APIserver发起请求就可以了.
Session/Cookie
session/cookie 是对http无状态特点的补偿
比如我们现在进行网络请求,我们多次进行网络请求,server是不知道是不是同一个用户的,比如我们进行购买一个商品,我们再次访问购买一个商品,由于http无状态的特点,server不知道是不是之前的某一个用户
cookie
cookie 主要是用来记录用户状态的,区分用户,状态是保存在客户端的
但我们客户端进行http请求的时候,server会生成一个cookie,会通过http响应报文,在报文头部添加一个字段,然后把cookie传给客户端,客户端将这个cookie保存下来,客户端在后续的http请求,把之前的cookie添加到http的请求报文的头部添加cookie字段,传给server就可以了
客户端发送的Cookie在http请求报文的Cookie首部字段中
服务端设置http响应报文的Set-Cookie首部字段返回给客户端
怎样修改cookie?
- 通过新 Cookie 覆盖旧的,覆盖原则,name,path,domain等需要和远cookie保持一致才可以覆盖,字段要一致
怎样删除 Cookie:
也是通过覆盖
- 新 Cookie 覆盖旧的Cookie
- 覆盖规则,字段要和原来保持一致
- 设置 Cookie 的 expires=过去的一个时间点或者maxAge=0
怎样保证cookie安全?
1. 对 cookie 进行加密处理
2. 只在 https 上携带 cookies
3. 设置 cookie 为 httpOnly,防止跨站脚本攻击
session
session也是用来记录用户状态,区别用户的,状态存放在服务端的
关系:
session 需要依赖 cookie 的机制来实现
session 工作流程:
当客户端向server端发送请求的,server会根据这个用户生成一个sessionID,然后当给客户端返回给客户端相应报文的时候吗,会通过http相应头部的Set-Cookie,将sessionID同步给客户端,然后客户端下次请求的时候,将这个sessionID放到http请求头的Cookie字段,给server,那么server就知道是哪个用户了。