HTTP协议概述
HTTP的发展历史
HTTP/0.9
是个简单的文本协议,只能获取文本资源。它的设计不可避免地受到时代的限制。HTTP/1.0
在1996年正式发布,多方面增强,确立了大部分现在使用的技术,形式上跟现在的HTTP
差别不大,但它不是正式标准。HTTP/1.1
是目前互联网上使用最广泛的协议,功能也非常完善。HTTP/2
基于Google的 SPDY 协议,注重性能改善。HTTP/3
基于Google的 QUIC 协议,是将来的发展方向。
HTTP是什么?HTTP又不是什么?
HTTP 就是超文本传输协议即 HyperText Transfer Protocol,是一个应用层的协议,通常基于 TCP/IP,能够在网络的任意两点之间传输文字、图片、音频、视频等数据。它可以拆成三个部分进行讲解,分别是超文本、传输和协议。
- 所谓文本表示
HTTP
传输的不是TCP/UDP
这些底层协议里被切分的杂乱无章的二进制包,而是完整的、有意义的数据,可以被浏览器、服务器这样的上层应用程序处理。 - 超文本是包含文字、图片、音频和视频等的混合体,最关键的是含有超链接。
HTTP 不是单独存在的实体、不是编程语言、不是一个孤立的协议。
- HTTP 通常跑在
TCP/IP
协议栈之上,依靠IP
协议实现寻址和路由、TCP 协议实现可靠数据传输、DNS 协议实现域名查找、SSL/TLS 协议实现安全通信。此外,还有一些协议依赖于HTTP,例如WebSocket、HTTPDNS等。
TCP/IP网络分层模型
分层的设计理念,把复杂的网络通信划分出多个层次,再给每一个层次分配不同的职责,每层只专心做自己的事情就好,用分而治之的思想把一个“大麻烦”拆分成了数个“小麻烦”,从而解决了网络通信的难题。
TCP/IP
协议栈的层次图如下:
TCP/IP
协议总共有四层。每一层需要下层的支撑,同时又支撑着上层,任何一层被抽掉都可能会导致整个协议栈坍塌。
- 第一层叫链接层,负责在以太网、WiFi这样的底层网络上发送原始数据包,工作在网卡这个层次,使用MAC地址来标记网络上的设备,所以有时候也叫MAC层。
- 第二层叫网络层,IP 协议就处于这一层。在链接层的基础上,用IP地址取代MAC地址,把许许多多的局域网、广域网连接成一个虚拟的巨大网络,在这个网络里找设备时只要把IP地址再“翻译”成MAC地址就可以了。
- 第三层叫传输层,这层协议的职责是保证数据在IP地址标记的两点之间进行传输。
- 第四层叫应用层,有各种面向具体应用的协议。例如Telnet、SSH、FTP、SMTP等等。
MAC层的传输单位是帧frame
,IP层的传输单位是包packet
,TCP层的传输单位是段segment
,HTTP的传输单位则是消息或报文message
。但这些名词并没有什么本质的区分,可以统称为数据包。
OSI网络分层模型
OSI,全称是开放式系统互联通信参考模型(Open System Interconnection Reference Model)。
两个分层模型的映射关系如图所示:
TCP的三次握手和四次挥手
三次握手就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的发送和接收能力是否正常。
开始时客户端处于Closed
的状态,服务端处于Listen
状态。 进行三次握手:
- 第一次握手:客户端给服务端发一个
SYN
报文,随机生成序列号seq
。此时客户端处于SYN_SEND
状态,等待服务器的确认。 - 第二次握手: 当
Server
收到Client
的SYN
报文段。对这个SYN报文段进行确认后,发送ACK报文,是用来应答的,设置为对方seq+1
。同时,发送SYN请求信息,初始化序列号seq
。服务器端将上述信息一并发送给客户端,此时服务器进入SYN_RECV
状态。 - 第三次握手:客户端收到
SYN
报文后,会发送一个ACK
报文。此时客户端处于ESTABLISHED
状态。服务器收到ACK
报文之后,也处于ESTABLISHED
状态,此时,双方已建立了连接。
断开连接时,当Server收到
FIN
报文时,可能不会立即关闭,所以先发送ACK
报文给客户端。等到Server端所有的报文都发送完毕,才能发送FIN
报文,因此ACK+FIN
不能一起发送,所以需要四次挥手。
HTTP报文
HTTP协议的请求报文和响应报文的结构基本相同,由三大部分组成:
- 起始行
start line
:描述请求或响应的基本信息; - 头部字段集合
header
:使用key-value形式更详细地说明报文; - 消息正文
entity
:实际传输的数据。
这其中前两部分起始行和头部字段通常合称为请求头或响应头,消息正文又称为实体,但与header
对应,很多时候就直接称为body
。
HTTP协议规定报文必须有
header
,但可以没有body
,而且在header
之后必须要有一个“空行”,也就是CRLF
,十六进制的0D0A
。
请求行
简要描述了客户端如何操作服务器端的资源。请求行由三部分构成,使用空格来分隔:
- 请求方法
- 请求目标
- 版本号
状态行
服务器响应的状态,同样也是由三部分构成:
- 版本号
- 状态码
- 原因