网络基础(一) HTTP协议

前言

不论iOS还是Android开发, 也不论客户端前端还是后端, 网络都是我们是在工作中或者自我知识储备体系中必不可少的一部分. 推荐大家读HTTP权威指南, 或者图解TCP/IP图解HTTP

一 HTTP是什么

全称超文本传输协议, HTTP协议是TCP/IP协议族中的一种, 是他的一个子集! 同时, HTTP协议建立在TCP/IP之上的协议.我们先来介绍一下TCP/IP

1 TCP/IP协议族

TCP/IP协议族, 按层次分为(在OSI模型中, 应用层又被分为应用层、表示层、会话层):

  • 应用层, 直接向用户提供服务的网络通信服务. FTP(文件传输协议), DNS(域名解析服务), 包括HTTP都属于这一层的协议
  • 传输层, 负责网络连接中计算机之间的数据传输. TCP(传输控制协议)和UDP(用户数据报文协议)都属于这一层的协议
  • 网络层, 负责处理流动于网络上的数据包(数据传输最小单位).IP(网际协议)是属于这一层的协议! 这一层规定了通过什么样的路径使两台计算机传输数据给对方. 通俗点说, 就是网络层负责选条传输线路来传给对方
  • 数据链路层, 负责处理硬件交互(所有硬件包括网卡, 适配器, 光驱, 光纤等等)
    他们的关系如下图
    网络基础(一) HTTP协议

2 IP、TCP、DNS协议

HTTP协议与这三个协议密不可分

2.1 IP

全称Internet Protocol(网际互连协议), 位于网络层! IP 协议负责传输, 作用是把各种数据包传送给对方. 但是想要保证正确传输到对方, 需要满足两个重要的条件

  • IP 地址, 是IP协议提供的一种统一的地址格式, 它为互联网上的每一个网络和每一台主机分配一个逻辑地址, 以此来屏蔽物理地址的差异. 所以IP地址和IP完全是两个不同概念
  • MAC地址(局域网地址), 物理设备地址, 一般一个MAC地址对应一个网卡

2.2 TCP

全称Transmission Control Protocol(传输控制协议), 位于传输层, 提供可靠的字节流传输服务.

  • 字节流是在传输过程中, 为了方便传输, 把大块的数据分割成若干个以报文段位单位的数据包进行传输管理的服务.
  • 可靠性是指在传输的过程中, 要保证对方准确可靠的收到了我传输的数据
  • TCP使用三次握手策略保证数据传输

一句话, TCP 协议为了更容易传送大数据才把数据分割, 而且 TCP 协议能够确认数据最终是否送达

2.3 DNS

全称Domain Name System(域名服务系统), 位于应用层, 负责提供域名到IP地址之间的域名解析服务. 比如我们经常访问的网址都根据主机名称来访问, 如https://www.baidu.com/而DNS在访问时会把主机名解析成IP地址

换句话说, DNS协议的作用就是通过域名找IP地址(也可以逆向反查域名)

二 HTTP报文

HTTP 报文: 用于 HTTP 协议交互的信息. 请求端(客户端)的 HTTP 报文叫做请求报文, 响应端(服务器端)的叫做响应报文. HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文 本

1 报文首部和报文主体

HTTP 报文大致可分为报文首部和报文主体两块. 两者由最初出现的 空行(CR+LF)来划分. 请求一定有报文首部, 但不一定有报文主体

1.1 报文首部

服务端或者客户端需要处理的请求或响应的内容及属性, 包括
请求行/响应行

  • 请求方法类型如GET, POST等/响应状态码如200等
  • URL, 统一资源定位符, 网址/状态码描述
  • 协议的版本号, 如HTTP1.1

请求头/响应头

  • 多个首部字段以key - value形式
1.2 报文主体

也就是请求体, 内容是应被发送的数据. 如POST请求携带的参数信息, 就在请求体中携带传输

2 请求报文和响应报文

2.1 请求报文结构网络基础(一) HTTP协议

请求报文
网络基础(一) HTTP协议

2.2 响应报文结构

网络基础(一) HTTP协议
响应报文网络基础(一) HTTP协议

3 TCP/IP协议族传输过程中的报文

网络基础(一) HTTP协议

4 报文主体和实体主体

报文
是 HTTP 通信中的基本单位, 由 8 位组字节流组成
实体
是请求或响应在传输时携带的有效载荷数据(如携带图片,视频, 压缩包等), 其内容由实
体首部和实体主体组成

HTTP 报文的主体用于传输请求或响应的实体主体
报文主体通常等于实体主体. 只有当传输中进行编码操作时, 实体主体的内容发生变化, 才导致它和报文主体产生差异

5 传输编码

5.1 压缩传输

就是HTTP协议中的内容编码, 该编码方式会有携带的实体内容进行压缩, 此种方式会保持数据信息原样.主要由以下几种方式

  • gzip(GNU zip)
  • compress(UNIX 系统的标准压缩)
  • deflate(zlib)
  • identity(不进行编码)

5.1 分包传输

即把主体携带的数据切割成块, 分块传输编码. 在 HTTP 通信过程中,请求的编码实体资源尚未全部传输完成之前, 浏览器无法显示请求页面. 在传输大容量数据时,通过把数据分割成 多块,能够让浏览器逐步显示页面. 在iOS中, 图片的一截一截加载也是分包传输

三 HTTP请求方式和状态码

1 请求方式

HTTP中请求方式包括, POST、GET、HEAD、PUT、DELETE、OPTINONS, 这些方法用来告知服务器客户端想干嘛. 我们先看看RFC文档定义的几个请求特性

  • 安全性: 不应该引起Server端的任何状态数据变化
    GET, HEAD, OPTHIONS
  • 幂等性: 同一个请求方法执行多次和执行一次的效果完全相同
    GET,PUT,DELETE
  • 可缓存性: 请求是否可以被缓存, 比如请求过程中间可能经过很多层级,代理服务器, 这里代理服务器就可以对请求进行缓存
    GET,HEAD

1.1 POST

用来传输实体主体. 虽然用 GET 方法也可以传输实体的主体, 但一般不用 GET 方法进行传输. 虽说POST的功能与GET 很相似, 但 POST 的主要目的并不是获取响应的主体内容.

POST的请求的参数不是明文的, 而是把参数以key - value形式放在请求体中, 这在一定程度上保证了安全性.

POST请求于服务端来说是非安全性的, 幂等的和不可缓存的

1.2 GET

主要用来获取资源. GET 方法用来请求访问已被 URI 识别的资源. 指定的资源经服务器端解析后返回响应内容. 也就是说, 如果请求的资源是文本, 原样返回;如果是像 CGI(Common Gateway Interface, 通用网关接 口)那样的程序, 则返回经过执行后的输出结果

GET的请求的参数是明文的, 以?的形式拼接在URL后面, 这是非常不安全的, 并且请求的数据一般偏小.

GET请求于服务端来说是安全性的, 幂等的和可缓存的

1.3 PUT

一般用来传输文件

2 状态码

  • 1xx: 信息状态码, 属于临时响应, 一般禁止服务端发送此状态码
  • 2xx: 成功状态码, 200 响应成功
  • 3xx: 重定向状态码, 301,302
  • 4xx: 客户端错误状态码, 401,404, 一般是客户端发起的请求本身存在问题
  • 5xx: 服务端错误状态码, 501,502, 一般是服务端server存在问题

2.1 200

请求正常处理, 返回200

2.2 204

请求处理成功, 但是没有资源返回, 即返回的报文中不包含实体主体部分, No Content

2.3 301

永久重定向, 表示请求的资源已被分配了新的地址, 以后应使用资源现在所指的地址.

http://example.com/sample
// URL路径后面没有添加 / , 就会引发301

2.4 401

客户端的请求报文中有语法错误

2.5 404

服务端无法找到请求的资源. 除此之外, 也可以在服务器端拒绝请求且不想说明理由时使用

2.6 500

服务端内部错误(大概率代码逻辑错误). 也有可能是 Web 应用存在的 bug 或某些临时的故障

2.5 502

网关错误

若想了解其他状态码含义, 请看这里

四 HTTP建立请求流程

就是我们经常听说的, 三次握手,通道建立, 四次挥手

1 三次握手

通过TCP的三次握手策略, 完成HTTP连接的建立, 握手过程中使用了 TCP 的标志(flag) —SYN(synchronize, 可以理解为同步报文)和ACK(acknowledgement, 可以理解问确认报文)

  • 客户端发起SYN同步报文, 连接建立的请求报文
  • 服务端端返回同步ACK报文
  • 客户端确认收到ACK报文

连接建立开始进行HTTP传输, 若在握手过程中某个阶段莫名中断, TCP 协议会再次以相同的顺序发送相同的数据包

2 四次挥手

  • 客户端发起连接断开,FIN终止报文
  • 服务端返回确认报文, 此时S端可能正在进行数据传输
  • 服务端发起连接断开,FIN携带ACK终止报文
  • 客户端收到确认返回ACK报文, 连接终止
    网络基础(一) HTTP协议

五 HTTP的特点

1 无连接

也叫非持久连接, 通俗点讲, 就是每次进行数据交互, 都需要重新建立HTTP连接三次握手, 通道建立, 这次数据交互完了, 马上就四次挥手关闭了数据通道. HTTP初始版本都是这种连接方式, 因为当时传输数据量很小

在HTTP1.1的时候, 随着传输的数据量越来越大为了解决上述TCP连接问题, 引入了持久连接的概念. 在一定时间内, 只要任意一端没有明确提出断开连接, 则保持 TCP 连接状态. 持久连接有以下几个特点:

  • 减少了TCP频繁建立和断开造成的额外开销, 减轻了服务端和客户端的负载
  • 节省的时间用来做传输, 提高了传输的效率

1.1 设置持久连接

在HTTP请求报文的首部字段中:

  • Connection: keep-alive 代表持久连接
  • time: 100 代表本次持久连接时长
  • max: 本次连接最多可以发送多少个HTTP请求

1.2 持久连接是否断开

在HTTP响应报文的首部字段中:

  • Content-length: 1024(总数据长度), 可以根据已经收到数据大小和此数据对比
  • chunked 在post请求中, 每份数据包都会携带一个chunked, 只有最后一个数据包的值为空

2 无状态

HTTP是无状态协议, 它不对之前发生过的请求和响应的状态进行管理. 通俗点来讲, 同一用户多次发送HTTP请求时, S端不知道多次请求是同一用户

解决方案: Cookie/Session, 即缓存

本文完

我是个写代码的小学生, 如有不足, 万望不吝指教

参考资料:
图解HTTP
RFC中文文档