HTTP
HTTP是一种应用层
的超文本传输协议,这就意味着它能够传输包括文字、图片、音频、视频等格式的内容。
HTTP从1.1之后开始支持长连接
,但长连接并不意味着永久连接。
HTTP是无状态
的,同一个客户端对服务端多次请求,服务端无法识别是否是同一个用户,因此引入了Cookie和Session技术。
HTTP报文
HTTP报文分为请求报文和响应报文,每一种报文均由三部分组成,它们分别是请求行、请求头、请求体
,响应行、响应头、响应体
。
请求行包含HTTP版本、方法、请求URL
三方面信息;请求头包含接收数据类型、完整URL地址、编码类型、设备信息、长连接、Cookie
等;请求体包含真正想传输给服务器的内容
,请求体不是必须的。
响应行包含HTTP版本、响应码、响应信息
三方面信息;响应头包含的内容和请求头类似
,不过Cookie字段变为了Set-Cookie;响应体则是服务端返回给数据内容
。
请求方法
HTTP请求方法除了常用的GET、POST
请求以外,还包括HEAD、PUT、DELETE、OPTIONS
四种请求方式。
GET和POST的区别在于,GET是安全的、幂等的、可缓存的
,POST是非安全的、非幂等的、非缓存的
。
为什么这么说呢?因为按照标准的GET和POST设计思路,GET请求不应该引起服务端数据的变化
,由于服务端数据不变,因此相同参数的GET请求每次返回的结果都应该是一样的
,针对这个特性,我们就可以把这部分数据缓存
起来使用。
另外,GET请求一般参数不超过2048个字符,POST请求则没有限制。
响应码
HTTP响应码一般包含1xx、2xx、3xx、4xx、5xx。当http请求只发送请求头不发送请求体的时候,如果服务器认为客户端可以授权连接,则会返回100,否则返回401,然后客户端可以接着发送请求体,以达到节约带宽的目的;200表示响应结果正常;301、302表示页面需要重定向;404表示页面不存在,403表示页面拒绝访问;500通常是服务器出了问题。
长连接
通过TCP协议与服务器建立连接时,每一次的请求都需要与服务器建立连接之后才能进行数据交换,这给网络请求带来了时间上的浪费。因此HTTP1.1之后增加了长连接的属性,在一次连接后,可以多次进行数据交互,直到时间过期或交互数超额才断开连接
。
通过设定请求头的Connection:kepp-alive; time-out:20; max:5
属性,我们可以与服务器建立长连接。其中time-out是指20秒后断开连接,max是指这20秒内最多进行5次数据交互。
Cookie和Session的区别
Cookie和Session其实就是一个JSON字符串,它们都是用来记录用户状态,他们的区别在于Cookie保存在客户端,Session保存在服务端
。
服务端收到客户端传输的账号密码等信息后,会为该用户生成一个SessionId,并通过响应头
的Set-Cookie
方式将SessionId和其他一些辅助参数传给客户端,客户端将这部分信息保存在本地,并且每次请求时都将此信息设置在请求头
的Cookie
中传输给服务器。
TCP和UDP
UDP
UDP是一种传输层的用户数据报协议,它的特点是无连接、尽最大努力交付、面向报文
。
无连接意味着它不需要事先与服务器建立连接
,也就没有断开连接的操作。由于这个无连接的特性,因此它无法保证传输的数据能够准确的到达服务器
(假设服务器刚好处于崩溃状态,数据就丢失了)。面向报文是指应用层给多少数据,它就传输多少数据,不会对数据进行拆分或合并传输
。无连接和面向报文给UDP带来的好处就是传输的速度更快
。
UDP具备差错校验
机制,不过笔者我不熟就不班门弄斧了。这里还有个复用、分用
的概念,TCP也是如此。简单的说,复用
就是指多个传输端口可以共用一个传输协议,分用
则是指当接收到数据时,通过一个传输协议可以回传给多个传输端口。
TCP
TCP协议是一种挺复杂的传输协议,它是一种传输层的传输控制协议,它的特点是需要连接、可靠交付、面向字节流、流量控制、拥塞控制
。
首先,需要连接
是指客户端在发起HTTP请求是,需要先跟服务端建立连接,建立连接的过程我们称之为三次握手
。
1. 客户端向服务端发送同步报文SYN
2. 服务端收到报文后向客户端发送同步确认报文SYN,ACK
3. 客户端再向服务端发送确认报文ACK
三次握手示意图
为什么要进行三次握手,而不是两次?
这主要是跟TCP的可靠性和超时重传机制有关,在第一次握手时可能因为网络拥塞导致服务器延迟收到,或者第二次握手时客户端延迟收到。此时客户端就会重新发送同步报文,当客户端重新发送同步报文后,如果收到了第一次发送的报文,就会直接丢弃,以第二次的为准。
建立连接后,客户端断就可以多次向服务请求数据,最后再断开连接,多次请求数据主要依赖HTTP的长连接属性。断开连接的过程我们称之为四次挥手
1. 客户端不需要在发送数据时会向服务端发送结束报文FIN。
2. 服务端收到后回复确认结束报文ACK,意思就是‘我知道你不再发数据了’。
3. 服务端不需要在发送数据时会向客户端发送结束报文FIN,ACK。
4. 客户端收到后回复确认结束报文ACK。
当双发都确认结束后,这条传输通道就关闭了。
这里面有个小概念是全双工通道,意思是通道的双发都可以主动向对方发消息。而不是两条通道。
可靠交付
和面向字节流
我们可以合起来理解,面向字节流的特性决定了TCP会通过自身的一套方式对应用层提交的数据进行拆分或合并,也就是说应用层一次性给10个字节,TCP并不一定一次性将这10个字节对外传输。数据被拆分或合并后,为了保证数据的准确性
其传输必须是有序
的,前一部分数据确认抵达后才会继续传输下一部分数据。如果其中因为网络问题触发了超时重传,那么重复的数据将被摒弃,因此TCP传输是不重复的
。有序、准确、不重复决定了TCP是可靠交付。
流量控制
涉及到一个叫滑动窗口
的概念。数据发送时会进入发送缓冲区
待命,每一次发送的数据量就是一个发送窗口
。由于双发所处的网络环境、设备环境可能不一致,当一方发送数据过多时就会导致接收方缓冲区溢出,因此发送方的每一次发送窗口大小是由接收方动态决定的
,这个机制就是所谓的流量控制。发送窗口是有编号的,并且是按序增大,假设接收方先接收到序号为3的数据,并未接收到1、2号数据,就会将序号为3的数据先放在数据缓存区,等待1、2号数据到达后才提交给应用层,所以我们说TCP传输是有序的
。
拥塞控制
主要方式是慢开始、拥塞避免。接收方会给发送方一个门限初始值,在达到门限值之前发送方每次发送的数据量呈指数增长,即1、2、4、8、16这样的方式,当达到门限值16后改为加法增长,17、18、19...当到达某个数值时,比如20,发现接收方的确认速度变慢了(可能因此网络拥塞等因素),就会将每次发送数据量重新从1、2、4...开始恢复。有一种变种控制方式快恢复、快重传
是指遇到拥塞后,数据量不会重新从1开始,而是从拥塞值的一半开始(比如20的一半,10)。
DNS解析
DNS解析实际上是将域名映射为IP地址的一个过程,采用的是UDP+明文
的方式进行传输。DNS主要通过递归查询
和迭代查询
两种方式解析域名。
递归查询
是一种层层向上的查询方式,由本地DNS > 根域DNS > 顶级DNS > 权限DNS向上查询,直到一方返回结果。
迭代查询
则是本地DNS直接向各级DNS进行查询方式,各级DNS会告知本地DNS“A可能知道结果”,本地DNS直接去找“A”获取IP地址。
DNS解析转发
是指DNS服务器为了减小压力,将DNS解析请求转发给了其他网络营运商(比如移动转发给电信),由该营运商提供解析结果。由于这种转发的方式,客户端可能会获得跟自身所处网络环境不一样的网络营运商的地址,就可能会出现请求响应慢的问题。
DNS劫持
是指伪装的DNS服务器通过53端口截获了DNS解析请求,并返回给客户端虚假的IP地址。我们可以通过httpDNS的请求方式,即使用HTTP协议直接向DNS服务器的80端口发起GET请求,并将目标域名和自身的IP地址拼接在URL参数上。
HTTP2.0
HTTP1.x版本在通过一个TCP链接中多次发起请求,后发起的请求会被先发起的请求阻塞
,也就是请求是串行的,必须等到前一个请求返回结果后才能接着处理下一个请求。针对这种现象,在请求数较多的情况下HTTP会建立多个TCP连接来获取数据,但是建立TCP链接需要经历握手与挥手流程,对时间和性能上也存在着一定的损耗。
2.0版本通过多路复用
的方式解决了这个问题,同一个TCP连接通过轮询的方式来发送请求,即前一个请求在等待数据的过程中,会接着判断队列中是否有其他请求,如果有则直接发送下一个请求。
2.0版本具备头部压缩
特性,会对HTTP请求头进行数据压缩,以达到更快的请求速度。
2.0版本采取了二进制
格式传递数据,而非文本传输
。
2.0版本使得服务端在建立连接后,能够主动推送
数据给客户端。
HTTPS
HTTP的数据传输采用的是明文
方式,安全性无法得到保障,因此产生了SSL协议用于HTTP数据加密,我们也就称之为HTTPS。SSL是早期的协议,现在一般采用是TLS。
TLS/SSL同样也位于应用层,严格上来说是位于HTTP应用层之下,TCP传输层之上的一个中间层。
当一个HTTPS请求发送给服务器时,会经历以下几个握手流程:
1. 客户端将支持的加密算法、随机数A、TLS版本传输给服务端;
2. 服务端选择一套算法、随机数B、证书传输给客户端;
3. 客户端进行证书校验、产生一个预主秘钥C,通过证书中的公钥对秘钥进行加密;
4. 客户端将加密后的预主秘钥C发送给服务端,服务端通过私钥进行解密得到秘钥C;
5. 双发通过随机数A、随机数B、预主秘钥C组装成会话秘钥后,使用会话秘钥发送一次加密的握手消息,来验证会话秘钥是否有效。
6. 验证成功后开始数据交互。
TLS握手流程示意图
HTTPS首先采用证书中的公钥和秘钥进行
非对称加密
,由于秘钥存在服务端中,不会在网络中传递,这样可以确保会话秘钥不会在传输过程中被恶意截获。但非对称加密(公、私钥不同)的性能相对耗时
,因此后续的数据交互均采用组装好的会话秘钥进行对称加密
。
`文中图片均来自慕课网--于海老师的教案`
网友评论