技术控

    今日:98| 主题:49471
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] 三分钟搞懂 HTTP Transfer-Encoding

[复制链接]
少年WODENGNI 发表于 2016-10-5 17:19:05
131 0

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
Transfer-Encoding是HTTP header 中的 entity header,所谓entity header就是专门用来描述消息体(message body)的头,像 Content-Length, Content-Language, Content-Encoding 都属于 entity header这一类,他们分别用来描述消息体的长度、语言、编码格式。那么 Transfer-Encoding 是用来干什么的呢?  
  通常,HTTP Response 中的 message body 是整个包一起发送到客户端的,Content-Length 消息头字段就是用来表示消息体的长度, 服务端必须精确地告诉客户端这个 message body 的长度是多少, 如果Content-Length 比实际长度短,会造成内容被截断,如果比实体内容长,客户端就一直处于pendding状态,直到所有的消息体都返回了才结束请求。但是对于HTTP持久连接,服务端发送消息体之前就要提前计算出消息体的长度作为Content-Length 发送给客户端,对于动态生成的内容在完全创建好之前是无法预知内容的长度的,这就要服务器缓冲内容直到完整的生成内容后计算出Content-Length的值才能发送给客户端。然而使用分块传输编码(Transfer-Encoding),数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小,这就是Transfer-Encoding 的作用。
  在消息头中指定    Transfer-Encoding: chunked就表示整个response将使用分块传输编码来传输内容,一个完整的消息体由n个块组成,并以最后一个大小为0的块为结束。每个非空的块包括两部分,分别为:块的长度(用十六进制表示)后面跟一个CRLF (回车及换行),长度并不包括结尾的回车换行符。第二部分就是数据本身,同样以CRLF (回车及换行)结束。最后一块是单行,只由块大小(0)以及CRLF组成,不包含任何数据。  
  现在就可以用Python实现一个简单的 HTTP Server 来指定 Response 的头 Transfer-Encoding。
  1. # -*- coding:utf-8 -*-
  2. import socket
  3. if __name__ == '__main__':
  4.     PORT = 8000
  5.     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  6.     sock.bind(('127.0.0.1', PORT))
  7.     sock.listen(1)
  8.     print 'Serving HTTP on port %s ...' % PORT
  9.     while 1:
  10.         conn, addr = sock.accept()
  11.         print conn, addr
  12.         request = conn.recv(1024)
  13.         # HTTP响应消息
  14.         conn.sendall("HTTP/1.1 200 OK\r\n")  # status line
  15.         conn.sendall("Content-Type: text/plain\r\n")
  16.         conn.sendall("Transfer-Encoding: chunked\r\n")  # 分块传输编码
  17.         conn.sendall("\r\n")  # 空行
  18.         conn.sendall("b\r\n")  # 11个字节的长度
  19.         conn.sendall("hello world\r\n")  # 消息体
  20.         conn.sendall("0\r\n")  # 最后一块0长度
  21.         conn.sendall("\r\n")
  22.         conn.close()
复制代码
用telnet请求测试:
  1. telnet localhost 8000
  2. Trying ::1...
  3. telnet: connect to address ::1: Connection refused
  4. Trying fe80::1...
  5. telnet: connect to address fe80::1: Connection refused
  6. Trying 127.0.0.1...
  7. Connected to localhost.
  8. Escape character is '^]'.
  9. get HTTP/1.1 /              # 发送GET请求
  10. HTTP/1.1 200 OK
  11. Content-Type: text/plain
  12. Transfer-Encoding: chunked
  13. b
  14. hello world
  15. 0
复制代码
最后引用Stack Overflow 上一句非常精辟的话作为总结:
      Transfer-Encoding: chunkedis needed when the total content length is unknown before the first bytes are sent.  
  相关参考:    一次完整的HTTP请求过程
友荐云推荐




上一篇:Alternative Text and Images
下一篇:STL中的Traits编程技巧
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表