vivapl has asked for the wisdom of the Perl Monks concerning the following question:

Desperate for wisdom!

Here is an example of code which preps a message to be sent
to a server. Packing works great, however when I receive a
response from the server, and print the content of that
response, I get some gibberish in front of every line
printed out. I'm assuming that my unpacking does not work.
Can someone please help me with this?
The message being returned is in the same format as the
message I'm sending.


$msg="1;SS"; $msg .= "\015"; my $cmd = pack "i/A*", $msg; print $socket $cmd; while( <$socket> ){ print unpack('A*',$_) . "\n"; }

sample output from server to this message using the above:
1. RC I10,49,54
the correct output should be:
1. RC 1. TI10,49,54
any help would be greatly appreciated

20030416 Edit by Corion : Added code tags

Replies are listed 'Best First'.
Re: Pack & Unpack
by BrowserUk (Patriarch) on Apr 16, 2003 at 15:20 UTC

    When you use the 'i/A*' format on pack the 'i/'part is requesting pack to prefix the string with a 4-byte integer denoting the length of the following string. This is the "garbage" you are seeing. To remove this, use the same format on the unpack as you used on the pack.

    print pack 'i/A*', "1;SS\015" ♣ 1;SS print unpack 'A*', pack 'i/A*', "1;SS\015" ♣ 1;SS print unpack 'i/A*', pack 'i/A*', "1;SS\015" 1;SS

    Or don't include it in the first place if you don't need it?


    Examine what is said, not who speaks.
    1) When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.
    2) The only way of discovering the limits of the possible is to venture a little way past them into the impossible
    3) Any sufficiently advanced technology is indistinguishable from magic.
    Arthur C. Clarke.
      If you want to avoid "mysterious bit flips", don't use platform-specific notation when sending stuff across the network. In your particular case, "i/A* should be "n/A*". Including "n" is equivalent to calling ntohs() on the number.

      --perlplexer
Re: Pack & Unpack
by vivapl (Acolyte) on Apr 16, 2003 at 15:32 UTC
    I tried to unpack using:
    unpack 'i/A*',$_; however it does not seem to work. One thing I've noticed is that if I try to unpack the message from the server whithout the while loop, I only get the first line back + the gibberish. If I do a while loop as in the code then I get all the message + gibberish. Could the problem lie in the fact that the message has a carriage return? I'm drawing a blank
      You should use a format like "n/A*" if your strings may have binary characters in them. But, if you do use this format, you cannot use <$socket> because the length may contain a "\n" character (e.g. if your string length is 10). You also shouldn't use <$socket> if your strings can contain arbitrary binary data which can include "\n". If you do use "n/A*", you should use read or sysread to read the data. You use the prepended length to tell when you have a complete message.
Re: Pack & Unpack
by vivapl (Acolyte) on Apr 16, 2003 at 18:07 UTC
    I've finally got the output I wanted.
    I've made the following change for unpacking:

    @tmprecv=<$socket>;
    $recv=join("",@tmprecv);

    print unpack("i/A*",$recv);
    Thanks for all the help