Dear monks,

I am sending a request to a game server and getting some buffer back via UDP, which works fine. I'm now trying to parse the buffer.

I have a class name package_reader as a member of another class for this. Reading a string works fine: I have created the following function to do it:

Notes:
* $self->index() gets the current position in the buffer
* $self->size() gets the total length() the buffer
* $self->skip(n) sets index += n


## read a string until a '\x00' is encountered (-> null termination of + strings in C!) sub read_complete_string { my ($self) = @_; my $string = ""; ## return empty string if we're already at the end of the buffer if($self->index() >= $self->size()) { return $string; } my $end_of_string = index($self->buffer(), "\x00", $self->index()) +; if(!($end_of_string)) { ## just read the rest of the buffer if there is no termina +tion $string = $self->read_buffer($self->size() - $self->index +()); } else { $string = $self->read_buffer($end_of_string - $self->index()); ## ignore the nullbyte '\x00' $self->skip(1); } return $string; }
The function read_buffer() and skip() are used in the code above and therefor also shown here:
## read the specified number of bytes from buffer, called by the other + read_* functions sub read_buffer { my ($self , $user_length) = @_; my $length = 1; $length = $user_length if $user_length; if(($self->index() + $length) > $self->size()) { print "$tag: WARN +ING: ##### read_buffer(): not enough data left, ignoring request to r +ead $length bytes! #####\n"; return 0; } my $val = substr($self->buffer(), $self->index(), $length); $self->index($self->index() + $length); print "$tag: DEBUG: read_buffer(): read raw data '$val' of length +$length, now at $self->{_index} (" . $self->data_left() . " bytes of +" . $self->size() . " left)\n"; return $val; } ## skips the given number of bytes sub skip { my ($self, $user_length) = @_; my $default_length; my $length; $default_length = 1; $length = $default_length; $length = $user_length if $user_length; $self->index($self->index() + $length); return $length; }
I do now need to parse the following C struct from the data:
struct client_t { short ping; int rate; char name[32]; // NULL-terminated byte clanTagPosition; // 0: prefix, 1: suffix char clanTag[32]; // NULL-terminated byte isBot; };
And I'm trying to get the ping of this client with the following code:
sub read_short { my ($self) = @_; my $sys_short_length = $Config{shortsize}; my $short = unpack('S', $self->read_buffer($sys_short_length)); return $short; } # elsewhere in the code: print "ping: " . $self->package_reader->read_short() . "\n";
I'm getting a number sometimes, but most of the time it's just empty or nonsense.

Two questions:
1) Is the read_short() function broken or do I have to do anything special when I print its return value (like use printf and format it properly)?
2) How do I unpack the byte from the C struct shown above? How do I know how long it is (how many characters do I have to read from my buffer)? Which template for 'unpack()' do I use?

Thanks in advance,

dichtfux

In reply to Parsing protocol data: unpack and bytes by dichtfux

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.