java发送帧格式数据格式_HTTP/2笔记之帧

零。前言

客户端和服务器端一旦握手协商成功接建立连接,端点之间可以基于HTTP/2协议传递交换帧数据了。

一。帧通用格式

下图为HTTP/2帧通用格式:帧头+负载的比特位通用结构:+-----------------------------------------------+

| Length (24) |

+---------------+---------------+---------------+

| Type (8) | Flags (8) |

+-+-------------+---------------+-------------------------------+

|R| Stream Identifier (31) |

+=+=============================================================+

| Frame Payload (0...) ...

+---------------------------------------------------------------+

帧头为固定的9个字节((24+8+8+1+31)/8=9)呈现,变化的为帧的负载(payload),负载内容是由帧类型(Type)定义。

帧长度Length:无符号的自然数,24个比特表示,仅表示帧负载所占用字节数,不包括帧头所占用的9个字节。默认大小区间为为0~16,384(2^14),一旦超过默认最大值2^14(16384),发送方将不再允许发送,除非接收到接收方定义的SETTINGS_MAX_FRAME_SIZE(一般此值区间为2^14 ~ 2^24)值的通知。

帧类型Type:8个比特表示,定义了帧负载的具体格式和帧的语义,HTTP/2规范定义了10个帧类型,这里不包括实验类型帧和扩展类型帧

帧的标志位Flags:8个比特表示,服务于具体帧类型,默认值为0x0。有一个小技巧需要注意,一般来讲,8个比特可以容纳8个不同的标志,比如,PADDED值为0x8,二进制表示为00001000;END_HEADERS值为0x4,二进制表示为00000100;END_STREAM值为0X1,二进制为00000001。可以同时在一个字节中传达三种标志位,二进制表示为00001101,即0x13。因此,后面的帧结构中,标志位一般会使用8个比特表示,若某位不确定,使用问号?替代,表示此处可能会被设置标志位

帧保留比特为R:在HTTP/2语境下为保留的比特位,固定值为0X0

流标识符Stream Identifier:无符号的31比特表示无符号自然数。0x0值表示为帧仅作用于连接,不隶属于单独的流。

关于帧长度,需要稍加关注: - 0 ~ 2^14(16384)为默认约定长度,所有端点都需要遵守 - 2^14 (16,384) ~ 2^24-1(16,777,215)此区间数值,需要接收方设置SETTINGS_MAX_FRAME_SIZE参数单独赋值 - 一端接收到的帧长度超过设定上限或帧太小,需要发送FRAME_SIZE_ERR错误 - 当帧长错误会影响到整个连接状态时,须以连接错误对待之;比如HEADERS,PUSH_PROMISE,CONTINUATION,SETTINGS,以及帧标识符不该为0的帧等,都需要如此处理 - 任一端都没有义务必须使用完一个帧的所有可用空间 - 大帧可能会导致延迟,针对时间敏感的帧,比如RST_STREAM, WINDOW_UPDATE, PRIORITY,需要快速发送出去,以免延迟导致性能等问题

二。报文头压缩和解压

和HTTP/1一样,HTTP/2报头字段包含一个或多个相关的键值对。报头字段会在HTTP请求/响应报头和服务器推送操作中使用。原先为文本字段,现在需要使用HTTP报头压缩进行序列化成报头分块,作为HEADERS 、 PUSH_PROMISE、CONTINUATION等帧的负载传输出去。

接收端合并接收到的帧组装成报头分块,解压缩还原报头集合。

一个完整的报头分块包含: - 单个包含报头终止标记END_HEADERS的HEADERS、PUSH_PROMISE帧,或者 - HEADERS、PUSH_PROMISE帧不包含的END_HEADERS标记,后续跟随一个或多个CONTINUATION帧,最后一个CONTINUATION帧包含了END_HEADERS标记。

报头压缩是有状态的,在一个完整的连接中,一方的压缩上下文环境,另一方的解压的上下文环境,都是需要具备的。报头解码失败需要作为连接错误COMPRESSION_ERROR对待。

报头块彼此之间离散,作为连续的同一类型帧序列存在,不存在交错帧以及来自其他类型帧或流。举一个例子,一个连续的HEADERS/CONTINUATION/PUSH_PROMISE帧序列,最后一个帧包含了END_HEADERS标记,表示一个报头完结。一个报头块逻辑上是一个帧,但是否完整取决于同类型连续的帧的最后一个包含END_HEADERS标记。

报头块作为HEADERS/PUSH_PROMISE/CONTINUATION等帧负载被一端发向另一端。接收端需要从HEADERS/PUSH_PROMISE/CONTINUATION等帧负载中进行组装报头块,执行解压还原报头集合,不管帧需要不需要被丢弃。接收端在解压时若不能够正常解压报头块,需要回应COMPRESSION_ERROR错误,然后终止连接。

三。HTTP/2定义的帧

规范定义了10个正式使用到帧类型,扩展实验类型的ALTSVC、BLOCKED等不在介绍之列。下面按照优先使用顺序重新排排序。

1. SETTINGS+-----------------------------------------------+

| Length (24) |

+---------------+---------------+---------------+

| 0x4 (8) | 0000 000? (8) |

+-+-------------+---------------+-------------------------------+

|R| Stream Identifier/0x0 (32) |

+=+=============================+===============================+

| Identifier (16) |

+-------------------------------+-------------------------------+

| Value (32) |

+---------------------------------------------------------------+

| Identifier (16) |

+-------------------------------+-------------------------------+

| Value (32) |

+---------------------------------------------------------------+

设置帧,接收者向发送者通告己方设定,服务器端在连接成功后必须第一个发送的帧。

字段Identifier定义了如下参数: - SETTINGS_HEADER_TABLE_S

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值