views:

504

answers:

3

I adopt select(), sysread(), syswrite() mechanism to handle socket messages where messages are sysread() into $buffer (binary) before they are syswritten.

Now I want to change two bytes of the message, which denote the length of the whole message. At first, I use following code:

my $msglen=substr($buffer,0,2); # Get the first two bytes
my $declen=hex($msglen);
$declen += 3;
substr($buffer,0,2,$declen); # change the length

However, it doesn't work in this way. If the final value of $declen is 85, then the modified $buffer will be "0x35 0x35 0x00 0x02...". I insert digital number to $buffer but finally got ASCII!

I also tried this way:

my $msglen=substr($buffer,0,2); # Get the first two bytes,binary
$msglen += 0b11; # Or $msglen += 3;
my $msgbody=substr($buffer,2); # Get the rest part of message, binary
$buffer=join("", $msglen, $msgbody);

Sadly, this method also failed. The result is such as"0x33 0x 0x00 0x02..." I just wonder why two binary scalar can't be joined into a binary scalar?

Can you help me? Thank you!

A: 

You cannot join two binary buffers in Perl directly all you have to do is call pack to get an ASCII and then join it and call unpack on it to get back.

serioys sam
There's no problem joining binary strings, but you have to join the right data.
brian d foy
+4  A: 
my $msglen=substr($buffer,0,2); # Get the first two bytes
my $number = unpack("S",$msglen);
$number += 3;
my $number_bin = pack("S",$number);
substr($buffer,0,2,$number_bin); # change the length

Untested, but I think this is what you are trying to do... convert a string with two bytes representing a short int into an actual int object and then back again.

Sol
You are right!I have been suffering with this problem for many days! Thank you very much!
bonny
+1  A: 

I have found another workable way -- using vec

vec($buffer, 0, 16) += 3;
bonny