PERLでバイナリスカラーを処理する
8220 ワード
PERL Handling Binary Scalar
1
[Question]:
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:
[Answer 2]:
vecを使います.
例:
Perl code
2
[Question]:
I am writing a Perl program that sends and receives messages from two sockets and acta as a switch. I have to modify the received messages received from one socket, prepend 3 bytes to the data, and finally send the modified messages to another socket. I adopt select()...sysread()...syswrite() mechanism to poll for messages between sockets. The received messages are stored in $buffer during modification. Now I can use following way to get the received messages:
1
[Question]:
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! [Answer 1]: 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
[Answer 2]:
vecを使います.
例:
Perl code
my
$buffer
=
"
/x00/x01
"
;
print
unpack
(
"
H*
"
,
$buffer
)
,
"
/n
"
;
vec
(
$buffer
,
0
,
16
)
+=
3
;
print
unpack
(
"
H*
"
,
$buffer
)
,
"
/n
"
;
2
[Question]:
I am writing a Perl program that sends and receives messages from two sockets and acta as a switch. I have to modify the received messages received from one socket, prepend 3 bytes to the data, and finally send the modified messages to another socket. I adopt select()...sysread()...syswrite() mechanism to poll for messages between sockets. The received messages are stored in $buffer during modification. Now I can use following way to get the received messages:
my $hexmsg = unpack("H*", $buffer);
my @msg = ( $hexmsg =~ m/../g );
then I can insert 3 bytes to @msg. However, I don't know how to pack the message in @msg into a scalar(such as $buffer) and send it to another socket by syswrite(). Can anybody help me? Thank you in advance! BTW, are messages in $buffer binary? [Answer]: Yes, messages in $buffer are binary (if I'm guessing what you mean by that correctly). If your only reason for unpacking it into @msg is to insert the bytes, don't. Use substr instead, and just write out the changed $buffer. For instance: substr( $buffer, 0, 0, "/x01/x02/x03" ); # insert 3 bytes at beginning.
If you are doing other things with @msg, you could continue to use that as well as doing the substr insert before writing it out, or you could use substr or pack or split or vec or a regex to parse out the pieces you need. You'd need to describe what you are doing to get more specific help.