HTTP/2 frame format
您目前处于:编程  2016年12月07日

以往的HTTP,我们习惯了和head /body 打交道。而在HTTP2,取而代之的是幀(Frame)。它将会成为协议中的最小通讯单位——所有的数据,head,body都会打包到Frame内发送。Frame 有很多类型,比如 header frame, data frame 。

开门见山,看看幀格式(头 9 字节是幀头部,后面的都是有效载荷):

Frame 构成定义

细化 length

Length 是指有效载荷(Payload)的长度。不包括Frame Header的长度。比如我们要发送一个16进制的 '12345678' 给对方,Length 就是 4,不是 8+ 4 = 12 。

细化类型 Type

细化 Flag

细化 Stream

为什么说需要标示流呢? 因为HTTP2场景下,TCP Connection 不再只有一对请求+响应了 —— 可以有多个响应。这些响应打包到多个 Frame,在一个 Connection 上混合交错的发。接收方必须知道每个 Frame 属于那个 Response,这就是流所标示的了。

案例

我们要发送 0x12345678,流编号为 10 ,类型为DATA,那么这个 Frame的16 进制表达就是:

Data Frame

数据帧是类型为0x0的幀。一个或者多个DATA frame可以一起来,携带HTTP请求的数据或者响应的数据。数据帧也可以包含任意一些填充字节。

#字段 Field

Pad Length : 填充字节长度(8bits)。

Data : 应用数据。

Padding : 填充字节。必须设置为0,接收的时候忽略。

#标记 Flag

END_STREAM (0x1) : 流结束标示。1表示结束。

END_SEGMENT (0x2) : 段结束标示。段是指示代理的合并时机。代理绝对不能跨越多个段边界来合并帧,转发帧的时候代理端必须保持片段的边界。

PADDED (0x8) : 填充标示。表示Pad Length 字段是可见的。

#错误处理

数据帧绝对需要与流相关联。如果接收到流标记字段是0x0的数据帧,必须响应一个类型为协议错误的连接错误。

数据帧遵从流量控制,并且只有在流是打开或者半封闭(远端)状态下才能够被发送。填充同样包含在流量控制中。如果数据帧在相关流不是在打开和半封闭(本地)状态下被接收,接收端必须响应一个类型为流关闭的流错误。

填充字节的总数取决于Pad Length 的值。如果填充物的大小大于帧有效载荷的大小,接收端必须作为类型为协议错误的连接错误。

请注意:为帧的大小加1字节可通过增加一个值为0的Pad Length 值的方法。


Reference:

https://segmentfault.com/a/1190000002605140

https://segmentfault.com/a/1190000002586816


转载请并标注: “本文转载自 linkedkeeper.com ”