在Perl中解压缩功能要求

时间:2016-01-21 15:45:24

标签: perl unpack

我在Perl中有一个函数,它以这种方式从模板中读取数据包:

sub read_packet {
  my $contents = shift;
  my @decode = unpack('nnnN', $contents);

  my $version = $decode[0];
  my $identifier = $decode[1];
  my $type = $decode[2];
  my $size = $decode [3];

  @contents = ($version, $identifier, $type, $size);

  return (@contents);
}

解包功能中的模板需要进行更改。现在 $ identifier 必须支持32位,因此根据PerlMonks: Pack/Unpack Tutorial (aka How the System Stores Data) (N) - > n,N“网络”(big-endian)顺序中的16/32位值。

所以这个功能被重写了这个小小的改变。现在,发送“数据包”的程序可能正在发送16/32位值。 客户要求我支持16/32位。如果数据包包含16位或32位标识符,我该怎么办?

2 个答案:

答案 0 :(得分:5)

如果这四个字段 all 该数据包包含,那么您可以检查$contents的长度

  • 如果格式为nnnN,则长度为2 + 2 + 2 + 4 = 10字节

  • 如果格式为nNnN,则长度为2 + 4 + 2 + 4 = 12字节

但是,如果这四个字段后面有数据,那么您必须尝试最常见的unpack模板并检查结果是否合理,如果失败则使用替代模板

答案 1 :(得分:2)

当协议以不兼容的方式更改时,版本也应该已更改。如果是这样,您可以使用以下内容:

sub read_packet {
  my $contents = shift;
  (my $version, $contents) = unpack('na*', $contents);

  if ($version < X) {
     return ( $version, unpack('nnN', $rest) );
  } else {
     return ( $version, unpack('NnN', $rest) );
  }
}

否则,您将根据数据包的大小确定其基础。但是,这需要传送数据包的大小,并非总是如此。幸运的是,这似乎确实如此,因此您可以使用以下内容:

sub read_packet {
  my $contents = shift;
  return unpack(length($contents) < 12 ? 'nnnN' : 'nNnN', $contents);
}