2016-01-21 3 views
2

У меня есть функция в 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 A 16/32 битное значение в сетевом порядке (big-endian).

Таким образом, функция была переписана с учетом этого небольшого изменения. Теперь программа, отправляющая «пакет», может отправлять 16/32-битные значения. Заказчик потребовал от меня поддержки как 16/32 бит. Что я могу узнать, когда пакет содержит 16 или 32-битный идентификатор?

+0

проверить размер пакета? – choroba

+0

@choroba, я не могу найти документ для этого, пелаза, можете ли вы указать мне на документацию. – crsuarezf

ответ

5

Если эти четыре поля все, что пакет содержит то вы можете проверить длину $contents

  • Если формат nnnN то длина будет 2 + 2 + 2 + 4 = 10 байты

  • Если формат nNnN то длина будет 2 + 4 + 2 + 4 = 12 байт

Однако, если есть данные после этих четырех полей, то вы должны попробовать самый общий unpack шаблон и проверить результат для здравомыслия, используя альтернативный шаблон, если он не

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); 
} 
Смежные вопросы