在 Perl 中解压函数需求
Unpack function requirement in Perl
我在 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 16/32 位"network"(大端)顺序的值。
所以这个函数被重写了这个小改动。现在,发送 "packet" 的程序可能正在发送 16/32 位值。
客户要求我同时支持 16/32 位。我怎样才能知道数据包何时包含 16 位或 32 位标识符?
如果这四个字段是数据包包含的全部那么你可以检查$contents
的长度
如果格式是nnnN
那么长度就是2 + 2 + 2 + 4 = 10字节
如果格式是nNnN
那么长度就是2 + 4 + 2 + 4 = 12字节
但是,如果这四个字段后面有数据,那么您必须尝试最常用的unpack
模板并检查结果的完整性,如果失败则使用替代模板
当协议以不兼容的方式更改时,版本也应该更改。如果是这样,您可以使用以下方法:
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);
}
我在 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 16/32 位"network"(大端)顺序的值。
所以这个函数被重写了这个小改动。现在,发送 "packet" 的程序可能正在发送 16/32 位值。 客户要求我同时支持 16/32 位。我怎样才能知道数据包何时包含 16 位或 32 位标识符?
如果这四个字段是数据包包含的全部那么你可以检查$contents
如果格式是
nnnN
那么长度就是2 + 2 + 2 + 4 = 10字节如果格式是
nNnN
那么长度就是2 + 4 + 2 + 4 = 12字节
但是,如果这四个字段后面有数据,那么您必须尝试最常用的unpack
模板并检查结果的完整性,如果失败则使用替代模板
当协议以不兼容的方式更改时,版本也应该更改。如果是这样,您可以使用以下方法:
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);
}