用Perl解包函数需求

用Perl解包函数需求,perl,unpack,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

我在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的说法:(N)->N,N是按“网络”(大端)顺序排列的16/32位值

所以函数被重写了,做了这个小改动。现在,发送“数据包”的程序可以发送16/32位的值。 客户要求我同时支持16/32位。如何知道数据包何时包含16位或32位标识符?

如果这四个字段都是数据包包含的,那么您可以检查
$contents

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

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


但是,如果这四个字段后面有数据,则您必须尝试最常见的
解包
模板,并检查结果是否正确,如果失败,则使用替代模板当协议以不兼容的方式更改时,版本也应该更改。如果是,您可以使用以下选项:

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);
}
sub-read\u数据包{
我的$contents=shift;
(我的$version,$contents)=解包('na*',$contents);
如果($version
否则,您将根据数据包的大小进行调整。然而,这需要通信的数据包的大小,但情况并非总是如此。幸运的是,这里的情况确实如此,因此您可以使用以下方法:

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);
}
sub-read\u数据包{
我的$contents=shift;
返回解包(长度($contents)<12?'nnnN':'nnnN',$contents);
}

检查包裹的大小?@choroba,我找不到文件,pelase,你能给我指一下文件吗。