代码之家  ›  专栏  ›  技术社区  ›  crsuarezf

打开Perl中的函数要求

  •  2
  • crsuarezf  · 技术社区  · 10 年前

    我在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);
    }
    

    需要对解包函数中的模板进行更改。现在 $标识符 必须支持32位,因此根据PerlMonks: Pack/Unpack Tutorial (aka How the System Stores Data) (N) ->n、 n“网络”(大端)顺序的16/32位值。

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

    2 回复  |  直到 9 年前
        1
  •  5
  •   Borodin    10 年前

    如果这四个字段是 全部的 然后您可以检查 $contents

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

    • 如果格式为 nNnN 那么长度将是2+4+2+4=12字节

    但是,如果这四个字段后面有数据,则必须使用最常见的 unpack 模板并检查结果是否正常,如果失败,则使用备用模板

        2
  •  2
  •   crsuarezf    10 年前

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

    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);
    }