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

Fellow Monks, I am new to sockets, in fact, so new I am still bright and shiny :-).

I have found a simple script using IO::Socket to connect across two machines.
The article says that if I only want to use it on one machine then just change the PeerAddr attribute to make it so (as Jean Luc would say).
Anyway here's the code for the receiver;

use IO::Socket; my $sock = new IO::Socket::INET ( LocalAddr => 'localhost', LocalPort => 10000, Proto => 'tcp', Listen => 1, Reuse => 1, ); die "Could not create socket\n" unless $sock; my $new_sock = $sock->accept(); while(defined(<$new_sock>)) { print $_; } close($sock);
This works fine and starts OK, waiting for input. Here's the caller
use IO::Socket; my $sock = new IO::Socket::INET ( PeerAddr => 'localhost', PeerPort => 10000, Proto => 'tcp', ); die "could not create socket\n" unless $sock; print $sock "Hello there\n"; close($sock);

So as soon as I start the caller script, the receiver script prints an error stating that $_ in the print statement was not initialised.

Or to be more precise;

Use of uninitialised value at ./receiver.pl line xx, <GEN1>, chnuk 1

Can someone please point me in the right direction to get this working? There must be something rather fundamental that both the author of the code and myself are not aware of.

Many thanks.
readey

Replies are listed 'Best First'.
(jeffa) Re: Using IO::Socket
by jeffa (Bishop) on Jan 10, 2002 at 22:35 UTC
    You are _this_ close!

    You need to print a "control line feed" after each send and receive, also, turn auto-flush on (error on my behalf - it's okay to do this, but not necessary - see Update at bottom):

    use IO::Socket qw(crlf); # now you can use CRLF constant $|++; # non-buffered
    Next, every time you send and receive (via print), use that CRLF constant:
    # in server: print $new_sock $_, CRLF; # in client: print $sock "Hello there", CRLF;
    Last, don't use defined in your server wait loop, and don't forget to ask the server for the answer after the client has asked the question. Here is the whole deal for clarity (i did remove $|++ to prevent cargo-culting):

    # server use strict; use IO::Socket qw(:crlf); my $sock = new IO::Socket::INET ( LocalAddr => 'localhost', LocalPort => 10000, Proto => 'tcp', Listen => 1, Reuse => 1, ); die "Could not create socket\n" unless $sock; my $new_sock = $sock->accept(); while(<$new_sock>) { print $new_sock $_, CRLF; } close($sock); #------------------------------ # client use strict; use IO::Socket qw(:crlf); my $sock = new IO::Socket::INET ( PeerAddr => 'localhost', PeerPort => 10000, Proto => 'tcp', ); die "could not create socket\n" unless $sock; print $sock "Hello there", CRLF; print $sock->getline(); close($sock);

    Oh yeah - go ye forth and get Network Programming with Perl.

    Update!
    runrig reminded me that $|++ flushes STDOUT by default, not the socket (silly /me), so that should be $socket->autoflush(), but, as of IO::Socket version 1.18 autoflush is on by default. Sorry about that. runrig++

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    F--F--F--F--F--F--F--F--
    (the triplet paradiddle)
    
Re: Using IO::Socket
by readey (Sexton) on Jan 11, 2002 at 13:32 UTC
    Thanks for the time and the code. A humbly appreciative Monk.