您的位置:首页 > 理论基础 > 计算机网络

简易HTTP协议解析

2015-09-01 19:24 549 查看
首先介绍一些必要的知识点。

TCP协议为操作系统底层协议,能够保证应用层获取到完整的、顺序一直的包序列。但TCP不提供具体的分包,需要上层协议自己解决。TCP发送给上层协议的数据是一个没有意义的字符串序列。如何解释这段序列,需要应用层定义,也就是应用层协议规范的内容。

应用层协议按格式一般可以分为文本协议和二进制协议。文本协议最常见的就是HTTP,二进制协议如websocket。无论是哪种协议,都需要对格式严格定义,以方便程序对字符串序列进行分包、拆包。



HTTP协议通过两种方式定义协议帧(一个HTTP请求或一个HTTP响应)结束标志。第一种是在http header中使用Content-Length头给出body长度,header与body使用\r\n\r\n分隔,这样我们就能够确定一个HTTP帧的开始与结束。另外一种是chunked编码的http帧,通过在header中使用Transfer-Encoding:chunked标志声明该编码方式,消息体由数量未定的块组成,并以最后一个大小为0的块为结束。每一个非空的块都以该块包含数据的字节数(字节数以十六进制表示)开始,跟随一个CRLF
(回车及换行),然后是数据本身,最后块CRLF结束。在一些实现中,块大小和CRLF之间填充有白空格(0x20)。最后一块是单行,由块大小(0),一些可选的填充白空格,以及CRLF。最后一块不再包含任何数据,但是可以发送可选的尾部,包括消息头字段。消息最后以CRLF结尾。



格式如下:

为简单起见,这里对HTTP服务端协议的解析,只考以Content-Length方式分帧的http帧,不考虑chunked编码的http协议解析。
流程图如下:




如上图所示,TCP提供的是字节流,所以会出现如下三种种情况:

缺包:当前接收到的字符不够一个完整的HTTP帧
粘包:当前接收到的字符串包含一个以上的HTTP帧
当前接收到的字符串正好是一个HTTP帧

针对以上三种情况,分别要做处理,出现粘包和缺包时,我们需要缓存尚未处理的部分留待下次接收到数据时一并处理。
根据如上流程图实现的PHP程序如下:
代码如下:

客户端代码如下:

源码地址:https://github.com/huyanping/learning-http-protocol


原创文章,转载请注明: 转载自始终不够
本文链接地址: 简易HTTP协议解析

转载请注明:始终不够 » 简易HTTP协议解析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: