Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
I've written a module to communicate with servers that use a sort of "little endian" communication protocol. The format of the messages is:
XXYYmessage
where XX is a little-endian two-byte message indicating the length of the message (without XXYY), and YY is an 'event code' such as 403 (public message). XX and YY are generally unrepresentable in plain text beacause they are lower than 'a'.

The module works for the first message. This is generally a login message. Also, the method I use for talking _back to_ the client is working.

The module is below:

package POE::Filter::LittleEndian; use strict; use warnings; use Carp qw{ croak carp cluck }; use constant FRAMING_BUFFER => 0; use constant EXPECTED_SIZE => 1; use constant EVENT_CODE => 2; #--------------------------------------------------------------------- +--------- sub new { my $type = shift; if (@_) { carp "POE::Filter::LittleEndian does not support any arg +uments!\n" } my $self = bless [ '', undef, undef, ], $type; $self; } #--------------------------------------------------------------------- +--------- sub get { my ($self, $stream) = @_; my @blocks; $self->[FRAMING_BUFFER] .= join '', @{$stream}; # we know what to expect, size wise if ( defined $self -> [EXPECTED_SIZE] ) { # if the length of the buffer is less than we had hoped for, e +xit. last if (length $self -> [FRAMING_BUFFER] < $self -> [EXPECTED +_SIZE]); # read in as much as we can my $chunk = substr($self -> [FRAMING_BUFFER], 0, $self -> [EXP +ECTED_SIZE]); # and then zap it, because we've read it. substr($self -> [FRAMING_BUFFER], 0, $self -> [EXPECTED_SIZE]) + = ''; # and now we need another LENGTH block so we zap this one... undef $self -> [EXPECTED_SIZE]; # and return to caller. push @blocks, $chunk; } # we dont know what to expect, this is a new packet. else { my $little_e = $self -> [FRAMING_BUFFER]; my ($length, $event) = unpack 'vv', $little_e; my $body; # tell our hackers what event they had. $self -> [EVENT_CODE] = $event; # lop off the event code and the length, the hacker has it in +the object. if ($length and (length $little_e >= 4 + $length)) { $body = substr($little_e, 4, $length); } $self -> [FRAMING_BUFFER] = $body; $self -> [EXPECTED_SIZE] = $length; } return \@blocks; } #--------------------------------------------------------------------- +--------- # 2001-07-27 RCC: The get_one() variant of get() allows Wheel::Xyz to # retrieve one filtered block at a time. This is necessary for filter # changing and proper input flow control. sub get_one_start { my ($self, $stream) = @_; $self->[FRAMING_BUFFER] .= join '', @$stream; } sub get_one { my $self = shift; if ( defined $self -> [EXPECTED_SIZE] ) { return [ ] if length($self->[FRAMING_BUFFER]) < $self->[EXPECT +ED_SIZE]; my $block = substr($self->[FRAMING_BUFFER], 0, $self->[EXPECTE +D_SIZE]); substr($self->[FRAMING_BUFFER], 0, $self->[EXPECTED_SIZE]) = ' +'; undef $self->[EXPECTED_SIZE]; return [ $block ]; } else { my $little_e = $self -> [FRAMING_BUFFER]; my ($length, $event) = unpack 'vv', $little_e; return [ ] unless ($length and $event); my $body; $self -> [EXPECTED_SIZE] = $length; if ($length and (length $little_e >= 4 + $length)) { $body = substr($little_e, 4, $length); } $self -> [EVENT_CODE] = $event; $self -> [FRAMING_BUFFER] = $body; return [ ] if length($self->[FRAMING_BUFFER]) < $self->[EXPECT +ED_SIZE]; my $block = substr($self->[FRAMING_BUFFER], 0, $self->[EXPECTE +D_SIZE]); substr($self->[FRAMING_BUFFER], 0, $self->[EXPECTED_SIZE]) = ' +'; undef $self->[EXPECTED_SIZE]; return [ $block ]; } return [ ]; # not sure why we'd get here, but best to be safe... } #--------------------------------------------------------------------- +--------- sub put { my ($self, $blocks) = (@_); return $blocks; } #--------------------------------------------------------------------- +--------- sub get_pending { my $self = shift; return undef unless length $self->[FRAMING_BUFFER]; return [ $self->[FRAMING_BUFFER] ]; } ###################################################################### +######### 1; __END__
You may notice that this is loosely based on POE::Filter::Block.

Basically, I've incorporated some of the methods from MP3::Napster, which also uses the protocol, and the aforementioned POE filter.

I think what's happening is I am inadvertently clobbering the [EXPECTED_SIZE] attribute of the object. I feel like I have a very good understanding of the code, and see what it's doing, but I cant seem to figure out where I am messing it up.

I have this great 'hexdump' code which converter graciously gave me, and I can see that in the middle of the next messages, there are 'overflows' of one message into the other with the little-endian bytes at the front.

I'd really appreciate it if somebody <!- except tilly of course -> could take a look at this for me, and see if there's something that doesnt add up.

--
Laziness, Impatience, Hubris, and Generosity.


In reply to Questions with a TCP stream protocol (POE, code) by deprecated

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



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (1)
As of 2023-06-03 10:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    How often do you go to conferences?






    Results (12 votes). Check out past polls.

    Notices?