以往的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 ” ©著作权归作者所有 |