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

#!/usr/bin/perl use IO::Socket; $SIG{CHLD} = sub {wait ()}; $main_sock = new IO::Socket::INET (LocalHost => '0.0.0.0', LocalPort => 1200, Listen => 5, Proto => 'tcp', Reuse => 1, ); while ($new_sock = $main_sock->accept()) { $pid = fork(); if ($pid == 0) { # Child process while (defined ($buf = <$new_sock>)) { print $new_sock `$buf`; } exit(0); } } close ($main_sock);

The above works functionally, but when I telnet from windows and run command ls, the output is a mess:

..
plit
    str
       strref
             swig.txt
                     system
                           tax.perl
                                   test.gif
                                           test_graph
                                                     test.txt
                                                             time
                                                                 tk
                                                                   tmp
                                                                      tty
                                                                         typeglo
b
 url
    use
       vt100
..

The above is what I get after run the command ls.

Seems windows prompt can't display vt100 correctly, how to fix this issue?

Replies are listed 'Best First'.
Re: Have trouble implementing a shell-alike script
by zwon (Abbot) on Sep 14, 2011 at 05:45 UTC

    Windows uses CRLF as line separator, but you're sending just LF. See Newline

    P.S. and AFAIK you're right about Win32 console -- it is does not compatible with vt100

Re: Have trouble implementing a shell-alike script
by Marshall (Canon) on Sep 14, 2011 at 09:51 UTC
    It appears to me that there is a bit of O/S and protocol confusion going on here. Perl is actually pretty smart about how it deals with this - it will do the "right thing" about LF (Line Feed) vs CRLF (Carriage Return, Line Feed), but you have to give it a clue.

    Here we are reading with one kind of a \n (the capture of the ls command on Unix) and desiring to write with another kind of \n (the socket write). Oh, yes both Windows and Network line termination is the same (CRLF). Unix line termination is just LF. Perl considers LF and CRLF the same for reading in line mode.

    I suggest this ...

    my @captured_output = split(/\n/,$ls_captured_line); ...then... foreach (@captured_output) { print socket "$_\n"; }
    At the moment, the Unix machine that I test with is down. However, the above code is in theory correct- check it out yourself! On read, \n means LF or CRLF. When Perl writes to Windows, a \n is CRLF. When Perl writes to a network socket, a \n is CRLF. I think the compiler can also figure out what to do with: join("/n", @captured_output);

    My point is that Perl can read lines terminated either way (\n meaning either just LF or CRLF). And further when Perl writes a \n, it will emit a LF or a CRLF depending upon what it is writing to. As weird as it sounds, Windows and Network \n is different than Unix \n.

        Thank you for making my point. If you click on your own link, you will see the below.
        A common misconception in socket programming is that \n eq \012 everywhere. When using protocols such as common Internet protocols, \012 and \015 are called for specifically, and the values of the logical \n and \r (carriage return) are not reliable.
        The link gives examples:
        print SOCKET "Hi there, client!\r\n"; # WRONG print SOCKET "Hi there, client!\015\012"; # RIGHT <- also wrong!
        The \r is wrong. I think that:
        print SOCKET "Hi there, client!\n"; #WORKS, on Unix or Windows!! #sends CR/LF: \015\012
        Basically do not ever put \r (CR) in a print statement. I agree.
        For the \n in the source code, Perl will send either LF or CRLF depending upon what it is taking to.
Re: Have trouble implementing a shell-alike script
by Anonymous Monk on Sep 14, 2011 at 04:42 UTC

    Seems windows prompt can't display vt100 correctly, how to fix this issue?

    Translate :) duh