(八) HTTP/2的各种帧定义

HTTP/2定义了多种帧的类型,每种类型都有一个唯一的8字节类型编码。在整个TCP连接或者是各个独立的流的建立和管理过程中,每种类型的帧都为特定的目的而服务。

DATA帧

DATA帧(数据帧,类型是0x0)传输与流相关联的任意的、可变长度的字节序列。例如,使用一个或多个DATA帧携带HTTP的请求和响应的有效载荷。

DATA帧可以包含填充字节序列。填充可以被添加到DATA帧,以掩盖消息的大小。因此,填充属于安全特性。

DATA帧的格式如下:

+---------------+
|Pad Length? (8)|
+---------------+-----------------------------------------------+
|                            Data (*)                         ...
+---------------------------------------------------------------+
|                           Padding (*)                       ...
+---------------------------------------------------------------+

各个字段解释如下:

  • Pad Length(填充长度):8比特字段,表示填充字节序列(即上图中的Padding)的字节长度。这个字段是可选的,只有在设置了PADDED标志位时才有。
  • Data(数据):具体应用数据,即帧的有效载荷减去其它字段的长度(其它字段是可选的)。
  • Padding(填充字节):填充字节不包含任何应用语义值。发送时必须将填充字节的值都设置为0。接收方没有义务验证填充序列,但是可以将非0的填充字节视为类型为PROTOCOL_ERROR的连接错误。

DATA帧定义了以下标志位:

  • END_STREAM (0x1):设置此标志位时表明当前帧是端点在流上发送的最后一个帧,从而导致流进入“半关闭”或“关闭”状态。
  • PADDED (0x8):设置此标志位表明帧中包含“填充长度”和“填充字节”这2个字段。

DATA帧必须与一个流关联起来。如果接收到的DATA帧的流标志位是0x0,那么接收方必须响应一个类型是PROTOCOL_ERROR的连接错误。

DATA帧受流量控制支配。只有当流处于“打开”或“半关闭(远程)”状态时,才能发送DATA帧。整个DATA帧都包含在流量控制中,数据、填充长度和填充字节字段都不例外。如果接收到的DATA帧关联的流不是“打开”或“半关闭(本地)”状态,那么,接收方必须响应一个类型是STREAM_CLOSED的流错误。

“填充字节”的总数由“填充长度”字段决定。如果填充字节序列的长度等于或大于整个帧的有效载荷,那么,接收方必须将其视为一个类型是PROTOCOL_ERROR的连接错误。

一个特殊情况是,可以通过将“填充长度”字节的值设置为0,为DATA帧增加一个字节的长度。

HEADERS帧

HEADERS帧(报头帧,类型是0x1)用于打开一个流,另外可以携带一个报头块碎片。HEADERS帧可以在状态为“空闲”、“保留(本地)”、“打开”、“半关闭(远程)”的流上发送。

HEADERS帧的格式如下:

+---------------+
|Pad Length? (8)|
+-+-------------+-----------------------------------------------+
|E|                 Stream Dependency? (31)                     |
+-+-------------+-----------------------------------------------+
|  Weight? (8)  |
+-+-------------+-----------------------------------------------+
|                   Header Block Fragment (*)                 ...
+---------------------------------------------------------------+
|                           Padding (*)                       ...
+---------------------------------------------------------------+

各个字段的解释如下:

  • Pad Length(填充长度):8比特位字段,表示填充字节序列(即上图中的Padding)的字节长度。这个字段是可选的,只有在设置了PADDED标志位时才有。
  • E(排他标志位):1比特位字段,表明流依赖是排他的。这个字段是可选的,只有在设置了PRIORITY标志位时才有。
  • Stream Dependency(流依赖):31比特位的流标志位,表示当前流依赖的那个流,即当前流的“父亲流”。这个字段是可选的,只有在设置了PRIORITY标志位时才有。
  • Weight(权重):8比特位的整数,表示流的优先级权重,范围是1-256之间。这个字段是可选的,只有在设置了PRIORITY标志位时才有。
  • Header Block Fragment(报头块碎片):报头块的片段。
  • Padding(填充字节):填充字节。

HEADERS帧定义了以下标志位:

  • END_STREAM(0x1):设置此标志位时表明当前帧是端点在流上发送的最后一个帧。携带END_STREAM标志位的HEADERS帧预示流的结束。然而,在相同的流中,携带END_STREAM标志位的HEADERS帧后面可以跟随一个或多个CONTINUATION帧。逻辑上,CONTINUATION帧是HEADERS帧的一部分。
  • PADDED (0x8):设置此标志位时表明帧中包含“填充长度”和“填充字节”字段。
  • PRIORITY(0x20):设置此字段时表明帧中包含“排他标志位”、“流依赖”和“权重”字段。

HEADERS帧的有效载荷包含一个报头块碎片。如果HEADERS帧中装不下报头块碎片,那么报头块碎片的剩余部分将被装到后面的CONTINUATION帧中。

HEADERS帧必须与一个流关联起来。如果接收到的HEADERS帧的流标志位是0x0,那么接收方必须响应一个类型是PROTOCOL_ERROR的连接错误。

HEADERS帧会改变流的状态。(参考(四) HTTP/2的流状态

HEADERS帧可以包含填充字节。填充字段和标志位与DATA帧的相同。填充字节的长度超过为报头块碎片保留的大小时,将导致一个类型是PROTOCOL_ERROR的连接错误。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
根据你提供的格式,我们可以按照以下步骤将fw文件转换为txt文件: 1. 打开fw文件进行读取和处理。 2. 创建一个空的字符串变量,用于存储转换后的数据。 3. 定义号和数据序号的初始值。 4. 依次读取fw文件中的数据块,每次读取2048个字节。 5. 根据格式将每个数据块转换为,并添加到字符串变量中。 6. 将最终得到的字符串变量写入到txt文件中。 下面是一个示例代码,用于实现上述转换过程: ```perl use strict; use warnings; # 定义常量 my $FRAME_SIZE = 2048; my $HEADER_CMD_CODE = 0x0; my $DATA_CMD_CODE = 0x02; my $FOOTER_CMD_CODE = 0x01; # 打开fw文件进行读取 open(my $fw_fh, '<', 'example.fw') or die "Cannot open fw file: $!"; # 创建空的字符串变量 my $txt_data = ''; # 定义号和数据序号的初始值 my $main_frame_num = 0; my $data_frame_num = 0; # 读取和处理fw文件中的数据块 while (read($fw_fh, my $buffer, $FRAME_SIZE)) { # 头 my $header = pack('C4nC2', $HEADER_CMD_CODE, $main_frame_num, 0x00, 0x800, 0x0000, 0x0000); $txt_data .= $header; # 数据 for my $i (0..$FRAME_SIZE-1) { my $byte = ord(substr($buffer, $i, 1)); my $data_frame = pack('C4n', $DATA_CMD_CODE, $main_frame_num, $data_frame_num, $byte); $txt_data .= $data_frame; # 更新数据序号 $data_frame_num = ($data_frame_num + 1) % 256; # 更新主号 if ($data_frame_num == 0) { $main_frame_num = ($main_frame_num + 1) % 16; } } # 尾 my $footer = pack('C4nC2', $FOOTER_CMD_CODE, $main_frame_num, 0x00, 0x0000, 0x0000, 0x0000); $txt_data .= $footer; } close($fw_fh); # 将转换后的数据写入txt文件 open(my $txt_fh, '>', 'output.txt') or die "Cannot open txt file: $!"; print $txt_fh $txt_data; close($txt_fh); print "Conversion completed successfully.\n"; ``` 请确保将代码中的`example.fw`替换为你实际的fw文件名,并根据需要修改`output.txt`为你想要的txt文件名。这段代码将fw文件转换为符合格式的txt文件。转换完成后,你可以在输出的txt文件中查看转换后的数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值