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

Reply via email to