HTTP 笔记(上)
date
Nov 3, 2018
slug
http-note-1
status
Published
tags
HTTP
summary
Http 的通信过程以及不同版本的对比
type
Post
HTTP 基础
网络间通信的大体流程
osi 模型较为复杂,一般常说的是五层模型:
物理层 -> 数据链路层 -> 网络层 -> 传输层 -> 应用层
下面这张图用来简单描述俩台通过路由器联系起来的主机的数据是如何传输的。
假设主机1的程序ap1向主机2的程序ap2传送数据。ap1先将数据交给第5层(应用层)。第5层加上必要的控制信息h5传递给下一层,以此类推。需要注意的是数据到达第2层(数据链路层)后,控制信息分成俩部分,分别加到本层数据单元的首部(h2)和尾部(t2);而第1层由于是比特流传送即0101...所以不必加上控制信息,但是物理层是从首部开始传递数据。
这一串比特流离开主机1后通过物理媒介传递到路由器,从路由器的第1层(物理层)依次上升至第3层(网络层)每一层都会对控制信息进行操作,操作后将控制信息剥去将剩下的数据向上传送,当到达第3层后就会根据首部的目的地址查找路由器中的路由表,找出转发分组的接口,然后从第3层向下传递至第1层,转为比特流之后传递给主机2,主机2的过程与上类似,最终程序ap2收到传输的数据。
在我们平时上网浏览网页时,通常都是我们的电脑与服务器的数据交互,中间过程不是像上述描述的只经过一个路由器这么简单,期间会经过dns服务器、cdn服务器等等。这里着重记录关于 http 部分的知识。
HTTP 不同版本特点对比
HTTP/0.9 :
- 只有一个 GET 命令
- 没有 header 等描述信息
- 服务器发送完毕,tcp连接被关闭
HTTP/1.0
- 增加 POST/PUT 等命令
- 增加 header & status code 信息
- 支持多字符集、多部分发送,缓存等
HTTP/1.1
- 使tcp连接持久化
- pipeline(客户端可以发送多个http请求,但是服务端必须按顺序返回)
- 增加host与其他命令(利用host中的端口判断具体属于node还是java等)
HTTP/2.0
- 数据以二进制传输(2.0之前数据传输是已字符串传输)
- 对于客户端发送的多个http请求,服务器返回时不用按照顺序返回,可以并行返回
- 头信息压缩,增加了推送等提高效率的功能
需要注意的是:
- 理论上来说一个tcp连接中可以存在多个http请求,但是目前的做法是http1.1中一个tcp链接上同时最多只有一个http请求
- 并发量一般指的是tcp连接的并发量
各个浏览器对应的tcp并发数量详情可查看:主流浏览器的HTTP最大并发连接数
HTTP 的三次握手
具体情况如上图,这里的 syn 代表同步位,seq 代表序号,ack 代表确认号。需要注意的是当首次握手发生时,即客户端进入 SYN-SENT状态前,不能携带数据,当发生二次握手时,即服务器进入SYN-RECV状态前,也是不能携带数据的,当发生第三次握手时即客户端进入ESTAB-LISHED状态前,可以携带数据。
为什么需要三次握手?
因为tcp要保证传输的数据可靠性,但是信道(数据链路层)传输是不可靠的。如何保证tcp传输的数据是可靠的?只能在tcp连接建立前保证通道畅通。因为在三次握手的过程中有网络延迟、包丢失等原因,所以才有了三次握手,三次握手是理论上的最小值。具体分析请参考:TCP 为什么是三次握手,而不是两次或四次? 、tcp建立连接为什么需要三次握手
补充:套接字(socket)
平常我们在使用自己电脑测试移动端页面或者是自己在写程序连接某项服务时都会使用 ip + 端口号 来连接,这是为什么呢?
因为这些做法都使用了tcp连接,而tcp把连接作为最基本的抽象。在tcp的俩端分别有俩个端点,端点叫做套接字。rfc 793 定义:端口号拼接到 ip 地址构成了套接字。如下图:
同一个ip地址可以有多个tcp连接,而同一个端口号也可以出现在多个不同的tcp连接中。
HTTP 报文格式
这是一个很简单的请求与响应报文格式图。需要注意的是响应报文的首部结尾是空行。响应报文中具体的status code 请参考:常见的HTTPRequest状态码说明