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

I like to use IO::Socket::INET to make a socket connection :)
If I have $sock as a filehandle object, can I see exactly what characters come through it? I tried that:
while <$sock>{ print; }
But that does not print all the characters. Lots of them are unprintable, other of them just screw up my terminal ;) How can I see them?
Does it make sense in what type of terminal (rxvt, telnet, linux) do I run the script? Does it make sense of the characters font or encoding?
Thanks in advance ;)

Replies are listed 'Best First'.
Re: I want to know exactly what comes through a socket
by ikegami (Patriarch) on Nov 23, 2005 at 21:37 UTC

    They're unprintable, so you can't see them by definition. You could replace them with some form of representation. For example,

    sub unchomp { $_ = $_.$/ foreach @_ ? @_ : $_; } while (<$sock>) { chomp; # Don't want to transform the newline. s/([^[:print:]])/sprintf("\\x{%02X}", ord($1))/eg; unchomp; print; }
    Untested.

    Update: Tested. Fixed bugs.

    Update: Here's an alternative representation (for charsets based on ASCII):

    sub unchomp { $_ = $_.$/ foreach @_ ? @_ : $_; } while (<$sock>) { chomp; # Don't want to transform the newline. s/([\x01-\x1F])/'^' . chr(ord('@')+ord($1))/ s/([^[:print:]])/sprintf("\\x{%02X}", ord($1))/eg; unchomp; print; }

    The first program outputs
    test\x{1}\x{2}\x{1D}test
    and the second outputs
    test^A^B^]test
    for the result of the Perl expression
    "test".chr(1).chr(2).chr(29)."test"

      ...sprintf("\\x{%02X}"...

      may work better and look better. Note the \\!


      DWIM is Perl's answer to Gödel
      Can I see their hex values? Or something like that ;]
      I see you use sprintf and ord, but that form of using is too complicated for my poor human mind ;) Could you enlighten me a bit, please?

        The top snippet does display their hex values (embeded in a Perl-style hex character escape).

        ord($1) returns the character number of the character in $1. For a tab, it would return the number '9'.

        sprintf("%02X", ord($1)) returns the hex character number of the character in $1. For a tab, it would return the string '09'.

        sprintf("\\x{%02X}", ord($1)) returns the hex character escape for the character in $1. For a tab, it would return the string '\x{09}'.

Hex Dump
by ikegami (Patriarch) on Nov 24, 2005 at 00:32 UTC

    A quick search revealed a few snippets which give hex dumps:
    kschwab's version
    OeufMayo's version

    For fun, I wrote my own version. I said for fun, so the style is unusual and the code could surely be optimized a bit. But it's tested.

    use strict; use warnings; use Algorithm::Loops qw( Filter ); my $blank = '.'; # or "\xFA"; open(my $fh, '<', @ARGV ? $ARGV[0] : '-') or die("Unable to open input file: $!\n"); binmode($fh); local $/ = \16; while (my $block = <$fh>) { my ($hex) = map { substr($_.(' 'x51), 0, 51) } join ' ', map /.{1,12}/sg, join ' ', map { sprintf '%02X', $_ } map ord, map /./sg, $block; my ($chr) = Filter { s/[^[:print:]]|\s/$blank/sg } $block; print("$hex $chr\n"); }

    Sample run:

    >perl hexdump.pl < hexdump.pl 75 73 65 20 73 74 72 69 63 74 3B 0D 0A 75 73 65 use.strict;..use 20 77 61 72 6E 69 6E 67 73 3B 0D 0A 0D 0A 75 73 .warnings;....us 65 20 41 6C 67 6F 72 69 74 68 6D 3A 3A 4C 6F 6F e.Algorithm::Loo . . . 0D 0A 20 20 20 70 72 69 6E 74 28 22 24 68 65 78 .....print("$hex 20 20 20 24 63 68 72 5C 6E 22 29 3B 0D 0A 7D 0D ...$chr\n");..}. 0A .
Re: I want to know exactly what comes through a socket
by johnnywang (Priest) on Nov 23, 2005 at 23:07 UTC
    Another non-Perl way is to use a packet snipper like ethereal, it can show you the stream in both directions, in both ascii and hex.