Re: Question on using Filter::Block
Tony Cook <[email protected]> Sun, 20 Jun 2010 19:24:25 +1000
| Newsgroups | gmane.comp.lang.perl.poe |
|---|---|
| Message-ID | <[email protected]> |
On Sun, Jun 20, 2010 at 09:31:48AM +0200, Stefan is using POE wrote:
> Hello,
...
>
> My Data are starting with a header, containing the message length in byte 2
> to 4 of my packet.
>
> My current design (plain IO::Socket):
>
> Reading: I'm reading the first 4 bytes (local $/= \4), take the length from
> bytes 2-4 and then read the rest, which is $lengths-4.
>
> Writing: writing to the client, I build the complete packet and put it on
> the line. very basic, but it works.
>
>
>
> I'm sure, POE will give a better way of doing this.
>
> I thought, I could use POE::Filter::Block, but this seems to need static
> block sizes or the length-prepended configuration, which I do not understand
> L to use.
>
>
>
> As a hint: in the first byte of the packet, there is always 0x07, so it
> would be feasible to calculate the length from the first 4 bytes,
> subtracting 0x0700000 from it ?!?
...
>
> sub stefans_decoder {
>
> my $stuff = shift;
>
> $$stuff =~ /^(.)(...)/;
>
> return hex($2);
>
> }
Is the data encoded as hex or in binary? From your note above it
appears to be in binary, but you're treating it as a hex string here.
Perhaps:
sub decoder {
my $stuff = shift;
length $$stuff >= 4 or return; # not enough to use
my @head = unpack "C*", substr($$stuff, 0, 4, "");
# is it big or little endian?
return $head[1] * 0x10000 + $head[2] * 0x100 + $head[3];
}
> sub stefans_encoder {
>
> my $stuff = shift;
>
> substr($$stuff, 0, 0) = "\7" . sprintf("%06x", length($$stuff));
>
> return;
>
> }
You're trying to fit 6 characters into a 3 byte buffer here, I guess
it is in binary. Maybe something like:
sub encoder {
my $stuff = shift;
my $len = length $$stuff;
substr($$stuff, 0, 0) = "\x07" + pack("C*", unpack("H*", sprintf("%06x", $len)));
return;
}
Tony