程序员该知道的HTTP
HTTP
1.1 HTTP报文
HTTP 报文是在 HTTP应用程序之间发送的数据块(用于HTTP协议交互的信息)。请求端(客户端)的HTTP报文叫做请求报文,响应端(服务器端)的叫做响应报文。
报文参数介绍:
- Remote Address :访问目标URL解析出来的IP地址
- Referrer Policy:Referrer用户知名当前请求的来源页面,对于同源的请求,会发送完整的url作为引用地址,防盗链
- accept:请求可以支持的响应格式列表信息
- accept-encoding:告知服务器本地浏览支持是压缩方式
- sec-fetch-dest:期望获得什么类型的资源
- sec-fetch-mode:navigate,表示这时一个浏览器的页面切换请求
- sec-fetch-site:表示一个请求发起的来源和目标资源来源之间的关系,cros-site:跨域请求,same-origin:同源请求
- upgrade-insecure-requests:1,表示当前浏览器可以处理https请求
- sec-fetch-user:?1 表示true
- user-agent:描述浏览器的信息
- server:web应用程序部署的容器。
1.1.1 报文组成
- 请求报文
- 响应报文
- 请求和响应结构类似:
1.1.2 HTTP 请求方法
1.1.3 响应状态码
状态码 | 介绍 |
---|---|
200 | OK |
301 | 代表永久性转移 |
302 | 代表暂时性转移 |
400 | 错误的请求 |
401 | Unauthorized 需要权限认证 |
403 | Forbidden 说明请求被服务器拒绝 |
405 | Method Not Allowed 发起的请求的URL不支持的方法 |
500 | Internal Server Error 服务器遇到一个妨碍它为请求提供服务的错误 |
502 | Bad Gateway 作为代理或网关使用的服务器从请求响应链的下一条链路上收到了伪响应 |
504 | Gateway Timeout 代理或网关等待超时 |
1.2 连接报文
1.2.1 TCP连接
1. 三次握手
0)准备工作
最开始的时候客户端和服务端都是处于CLOSED状态,主动打开连接的为客户端,被动打开连接的为服务器。TCP服务器先创建传输控制块TCB,时刻准备接收客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态
1)一次握手
客户端进程创建传输控制块TCB,然后发出请求报文,SYN=1,同时选择一个初始序列号seq=x。此时客户端进入了SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段不能携带数据,但需要消耗掉一个序号。
2)二次握手
TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该ACK=1,SYN=1,确认号是x+1,同时自己也初始化一个序列号seq=y,此时服务端进程进入SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是要消耗一个序号
3)三次握手
TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号x+1。此时TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
为什么要3次握手?
为了服务器、客户端双方都能明确自己和对方的收发能力正常。
2. 四次挥手
1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,序列号=u,此时客户端进入FIN-WAIT-1状态,TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时服务器进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态。即客户端已经没数据发送了,但是服务器若还要发送数据,客户端依然要接收。
客户端收到服务器的确认请求后,此时客户端进入FIN-WAIT-2状态,等待服务器发送连接释放报文。
3)服务器将最后的数据发送完后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器可能又发送了一些数据,假定序列号seq=w,此时服务器进入LAST-ACK(最后确认)状态,等待客户端确认。
4)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时客户端进入TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2*MSL的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
服务器收到客户端的确认后,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。
为什么关闭要4次,建立连接只要3次?
建立连接的时候,服务器收到客户端的SYN报文,把ACK和SYN放在一个报文里发送给客户端了。
而关闭连接时,服务器收到客户端的FIN报文,仅仅回了一个确认收到。因为自己可能还有数据要发送,等自己发完了。再发送FIN报文给对方表示可以关闭连接。这也就让服务器ACK和FIN分开发送,从而多了一次。
为什么客户端最后还要等待2MSL?
去向ACK消息最大存活时间(MSL) + 来向FIN消息的最大存活时间(MSL)。恰好就是2MSL。
- 保证客户端发送的最后一个ACK报文能到达服务器
- 等待2MSL时间,客户端就可以放心的释放TCP占用的资源和端口号。
1.3 HTTP2新特性
- 二进制分帧
- 头部压缩
- 多路复用
- 服务器推送