## HTTP的传输编码(Transfer-Encoding:chunked)
### 什么是传输编码?
传输编码在 HTTP 的报文头中,使用`Transfer-Encoding`首部进行标记,它就是指明当前使用的传输编码。
`Transfer-Encoding`会改变报文的格式和传输的方式,使用它不但不会减少内容传输的大小,甚至还有可能会使传输变大,看似是一个不环保的做法,但是其实是为了解决一些特殊问题。
简单来说,传输编码必须配合持久连接去使用,为了在一个持久连接中,将数据分块传输,并标记传输结束而设计的,后面会详细讲解。
在早年间的设计里,和内容编码使用`Accept-Encoding`来标记客户端接收的压缩编码类型一样,传输编码还需要配合`TE`这个请求报文头来使用,用于指定支持的传输编码。但是在最新的 HTTP/1.1 协议规范中,只定义了一种传输编码:分块编码(chunked),所以并不需要再依赖`TE`这个头部。
这些细节,后面都会讲到。既然传输编码和持久连接是息息相关的,那我们就先来了解一下什么是持久连接。
### 持久连接(Persistent Connection)
持久连接通俗来讲,就是长连接,英文叫 Persistent Connection,其实按字面意思理解就好了。
在早期的 HTTP 协议中,传输数据的顺序大致分为发起请求、建立连接、传输数据、关闭连接等步骤,而持久连接,就是去掉关闭连接这个步骤,让客户端和服务端可以继续通过此次连接传输内容。
这其实也是为了提高传输效率,我们知道 HTTP 协议是建立在 TCP 协议之上的,自然有 TCP 一样的三次握手、慢启动等特性,这样每一次连接其实都是一次宝贵的资源。为了尽可能的提高 HTTP 的性能,使用持久连接就显得很重要了。为此在 HTTP 协议中,就引入了相关的机制。
在早期的 HTTP/1.0 协议中并没有持久连接,持久连接的概念是在后期才引入的,当时是通过`Connection:Keep-Alive`这个头部来标记实现,用于通知客户端或服务端相对的另一端,在发送完数据之后,不要断开 TCP 连接,之后还需要再次使用。
而在 HTTP/1.1 协议中,发现持久连接的重要性了,它规定所有的连接必须都是持久的,除非显式的在报文头里,通过`Connection:close`这个首部,指定在传输结束之后会关闭此连接。
实际上在 HTTP/1.1 中`Connect`这个头部已经没有`Keep-Alive`这个取值了,由于历史原因,很多客户端和服务端,依然保留了这个报文头。
长连接带来了另外一个问题,如何判定当前数据发送完成。
### 判断传输完成
在早期不支持持久连接的时候,其实是可以依靠连接断开来判定当前传输已经结束,大部分浏览器也是这么干的,但这并不是规范的操作。应该使用`Content-Length`这个头部,来指定当前传输的实体内容长度。
下面举个例子,在保持持久连接的情况下,依赖`Content-Length`来确定数据发送完毕。
- CentOS运维手册
- CentOS6.9挂载额外的磁盘
- ACL(access control list)-权限控制
- 普通用户不能绑定80端口
- ssh8.1p1编译步骤
- 制作openssh8_1的rpm包
- 离线yum源维护
- 去除VIM中打开文件里有的^M字符
- Mysql运维手册
- CentOS6.9搭建Mariadb-Galera集群
- mysql编码报错
- haproxy代理mysql galera
- 常用sql
- MySQL通用知识点
- 修复断电损坏的MySQL数据表
- sync_binlog配置的分析
- Xtrabackup备份与恢复
- Innodb线程并发同步机制
- redo log
- 死锁分析
- 慢SQL分析
- nginx运维手册
- nginx日志分割
- proxy_set_header作用
- nginx优化
- url末尾不加/
- 负载均衡
- haproxy和nginx研究
- haproxy配置
- redis运维手册
- redis_5.0.8集群搭建
- Redis集群原理分析
- predixy的安装和配置
- redis优化
- NFS运维手册
- flock操作失败
- mongodb运维手册
- MongoDB开启用户认证
- shell编码规范
- HTTP
- HTTP的传输编码
- 性能分析
- java内存分析
- javaCPU分析