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

Hi Monks,

I'm trying to build a simple Telnet client that will send an APACS style message to a host. Creating the simple Telnet client is not a problem, but whenever I send a character the client interprets them as ASCII.

For example, using the code below I would like to send the ASCII character STX (start of text), so I send the hex equivalent - "02". The problem is that this is sent as an ASCII "02", so the host side sees this as "30 32" (in hex) instead of one byte hex value "02".
use IO::Socket::INET; $MySocket=new IO::Socket::INET->new(PeerPort=>'$port', Proto=>'tcp' +,PeerAddr=>"$ip"); $MySocket->send("02");
Any ideas how I can force the characters sent to "stay" in hex - even if this means using a different Perl module such as Net::Telnet?

Thanks in advance!

Replies are listed 'Best First'.
Re: Terminal Client
by JavaFan (Canon) on Oct 24, 2008 at 15:25 UTC
    I'd use Net::Telnet, but if I were to do it myself, I'd use pack:
    $MySocket->send(pack "H*", "02")
    should do the trick. Note that with the "H*" format given to pack, you can use a long string. pack "H*", "02020d0a" encodes STX STX CR NL.

    If it's just a single byte, I'd use:

    $MySocket->send("\x02")
      Thanks to everyone for the fast responses.

      The trick I was missing was to send the data as octal as per your suggestions. So for example if I use
      $MySocket->send("\02\8\03");
      The receiving end sees this as hex "02 38 03" (STX 8 ETX). Which is exactly correct. I can use the octal conversion functions as suggested by you guys to convert string "en mass".

      Many thanks for everyones help!
        \8 isn't valid octal. The result is a warning, and sending hex value 38. This just happens what you want, but \7 sends hex value 7. You don't want the \ in front of characters you want to send as they appear.
Re: Terminal Client
by Illuminatus (Curate) on Oct 24, 2008 at 15:06 UTC
    Use the hex or oct built-in functions...

    On a separate note, if you are connecting to a telnet daemon, you should probably use Net::Telnet

      Use the hex or oct built-in functions...
      That would only help if you run hex() and oct() on the receiving end:
      $ perl -wE 'print hex "02"' | od -a 0000000 2 0000001 $
      What the OP probably wants is pack:
      $ perl -wE 'print pack "H*", "02"' | od -a 0000000 stx 0000001
      But I advice him to use Net::Telnet.
Re: Terminal Client
by BerntB (Deacon) on Oct 24, 2008 at 15:05 UTC

    In the shell, try: perl -e 'print "\041\n";'

    Note that the char code is octal (you get a '!'). So don't write "02", write "\02". Since it is octal, if you want a cr, don't write "\013", write "\015"

Re: Terminal Client
by backstab (Novice) on Oct 25, 2008 at 05:10 UTC
    Is not the builtin chr for that?
    $MySocket->send(chr(0x02));
Re: Terminal Client
by Krambambuli (Curate) on Oct 24, 2008 at 15:18 UTC
    What if you use
    $MySocket->send(0x02);
    ?

    Krambambuli
    ---
      send assumes its argument is a string. 0x02 is 2, and as a string equals "2".

      I like your approach and I think this is what you meant:

      $MySocket->send("\x02");

      This seems the most straightforward to me. I have a personal preference of hex over octal.

      Update: Oops. At first I only saw JavaFan's pack approach in the reply below this. Be he already covered this approach too. Sorry for duplicates.