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

Folks I have a server and client perl programs written using IO::Socket. The server looks just fine (I think). But the client opens a connection to the server. It sends the message for the first time and receives it successfully. The second time, the client shows an empty message and the third time it fails with "cannot determine peer address". If I create a new socket everytime, that is, if I do my $remote = IO::Socket::INET->new() inside the loop in the client code, the code works just fine but I dont want to open a new connection everytime. Can you please tell me what should I do to open a connection to the server once and use it for n times. Thanks for your help CLIENT CODE:
use strict; use IO::Socket; my $remote = IO::Socket::INET->new( Proto => 'tcp', # protocol PeerAddr=> '127.0.0.1', # Address of server PeerPort=> "1426", # port of server Timeout => 90 ) or die "$!"; $remote->autoflush(1); for (my $i = 0; $i < 100 ; $i++) { $remote->send("Test \n"); # Send to Server my $line ; $remote->recv($line,256); # Receive echo from server print $line. "\n"; } close $remote; # Close socket
SERVER CODE:
use IO::Socket qw(:DEFAULT :crlf); use IO::File; use constant PIDFILE => "/tmp/prefork.pid"; use constant PREFORK_CHILDREN => 3; my $port = shift || 1426; my $socket = IO::Socket::INET->new( Proto => 'tcp', LocalPort => $port, Listen => 5, Reuse => SO_REUSEADDR, Type => SOCK_STREAM ) or die "Can't create listen socket: $!"; # create PID file, initialize logging, and go into background #init_server(PIDFILE); make_new_child() for (1..PREFORK_CHILDREN); exit 0; sub make_new_child { #my $child = launch_child(); my $child = fork; return if $child; do_child($socket); # child handles incoming connections exit 0; } sub do_child { my $socket = shift; while (1) { local $/ = "\n"; next unless my $c = $socket->accept; handle_connection($c); close $c; } close $socket; } sub handle_connection { my $x = shift; my $sz = <$x>; print $x "Testing\n"; }

Replies are listed 'Best First'.
Re: Cannot determine peer address
by kscaldef (Pilgrim) on Oct 25, 2005 at 06:38 UTC
    Look at do_child and handle_connection. You accept a new connection, read one line, write one line, then close the connection. Exactly what you see on the client side.
Re: Cannot determine peer address
by jesuashok (Curate) on Oct 25, 2005 at 06:40 UTC
    Hi,

    You have specified that there is no mistake in the Server Side Code. But I am sure that There is small mistake you have done in the server Side code only.

    sub handle_connection { my $x = shift; my $sz = <$x>; print $x "Testing\n"; }
    Insted do as follows sub handle_connection { my $x = shift; while ( <$x> ) { print $x "Testing\n"; } }

    The mistake what you have done is, You are getting only one line from the client ( But you are writting 100 lines from clinet side ). Once you get a single line from client you are closing the Client Side Socket Filehandle. So next time when the client tries to write another line into the server the broken connectio happened So you need to be very careful in handling the connection.

    Also It is advisable to use select function in server side program so that we can check all the events happening in both server and cient file handles.

    also there are some mistakes in client and Server for example in server side you are getting the port number as a command line arguement where as in client side the port is hard coded.

    "Keep pouring your ideas"