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

Hello friends, I’ve designed a fairly complex (aka inefficient) script to parse large (300 mb) files into usable EDI test data. I’m so proud of this script that every coffee break, lunch hour, and paycheck distribution, I find myself tinkering with it. I’ve about run out of things to do with this script, so I thought I would see about putting it on a centralized server and accessing it through telnet (like everything else I a use). My question is, is there a simple way to convert a script from printing to the screen – to printing to a socket in an interactive telnet session? It would be nice if I could pipe the remote socket input into <STDIN> and print data to the socket for the remote client. Is this crazy, foolish, or just another act of boredom? I know I could do it through CGI, but that’s been done, I know I could output it to a file for FTP (*Yawn*), but has anyone done this in a simple way that I could do without rewriting my entire script? I’ll worry about security later (I thought I’d never hear myself say that); I just want to know how hard this thing will be. I’ve got a little script for you, I can’t post the real deal because it contains proprietary information, but you get the idea. Thanks, and sorry for the rambling :)
use strict; my($first,$second,$result); BEGIN: print "Input first number (of two) for addition.\n"; $first = <STDIN>; chop($first); print "Input second number.\n"; $second = <STDIN>; chop($second); $result = $first + $second; print "$first \+ $second \= $result\n\n\n"; goto BEGIN;

Replies are listed 'Best First'.
Re: Piping sockets to STDIN
by l2kashe (Deacon) on Oct 11, 2002 at 03:24 UTC
    First off.. There is a module to deal with telnet access via perl (Net::Telnet I think). I didnt realize how much extra there is to telnet as opposed to a simple socket, but Ill show you one way of using a socket, and then leave finding the others ways as an excercise (Seeing as you are spending so much time with this :) ).... Basically I am treating the socket below just like any other filehandle
    #!/usr/bin/perl use IO::Socket; $socket = IO::Socket->new( PeerAddr => 'somehost_or_ip', PeerPort => 'some_port', Proto => 'tcp', Type => SOCK_STREAM, ); die "Cant connect to remote host!\n" if (!$socket); # Send a transmission print $socket "$some_output\n"; # Receive a resonse back chomp($line = <$socket>);
    Granted the above assumes a plaintext transmission, and there are more appropriate ways of playing with sockets, but this will get it done for you. As a test use that method to communicate with a mailserver (POP or SMTP), and get a feel for the transmission flow.

    If you need your transmission encrypted just go to search.cpan.org and search for Crypt, or Digest, and that should get you rolling, and for compression network transmission or otherwise, I like Compess::Zlib.

    have fun and happy hacking :)

    /* And the Creator, against his better judgement, wrote man.c */
Re: Piping sockets to STDIN
by chromatic (Archbishop) on Oct 11, 2002 at 06:36 UTC

    If you use the one-argument form of select, you can change the default output filehandle. You might also look at IO::Handle or its children and always pass in a filehandle and print to that.

Re: Piping sockets to STDIN
by robartes (Priest) on Oct 11, 2002 at 07:13 UTC
    Hi foxops,

    While you are probably better off, from the point of maintanability and readability of your code, to explicitely write to and read from your sockets, as in l2kashe's code above, you could start playing typeglob games to alias STDIN and STDOUT to your socket filehandles. Below is an example with regular files:

    use strict; open INPUT, "<flea.txt" or die "Blerch: $!\n"; open OUTPUT, ">camel.txt" or die "Hcrelb: $!\n"; local *STDOUT=*OUTPUT; local *STDIN=*INPUT; while (<STDIN>) {print}
    This will copy the input file to the output file. The local is not strictly necessary, but is certainly nicer. This way, you can locally alias STDIN and STDOUT to your sockets without changing the rest of your code.

    Oh, and to get simple sockets to telnet you can write to and read from without necessitating the various telnet control codes, you will probably have to use something like Net::Telnet, again as l2kashe said.

    CU
    Robartes-