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

Hi,
I'm trying to work with perl sockets, in win-32, with one server listening to multiple clients.

I was able to make the server listen to multiple clients and send data from each client to the server, but I'm unable to reply to each of the client from the server.

My query is like this:
client socket1 ----> "hello server" ----> server
client socket2 ----> "hello server" ----> server
client socket3 ----> "hello server" ----> server

server ----> "hello client1" ----> client socket1
server ----> "hello client2" ----> client socket2
server ----> "hello client3" ----> client socket3

My Client: ... ... use IO::Socket; $remote_host="some_host_name"; $remote_port=1234; #$soc=IO::Socket::INET->new("$remote_host:$remote_port") or die $@ +; $socket = IO::Socket::INET->new(PeerAddr => $remote_host, PeerPort => $remote_port, Proto => "tcp", Type => SOCK_STREAM) or die "Couldn't connect to $remote_host:$remote_port : $@\n"; #....do something with the socket print $socket "New host\n"; $answer=<$soc>; print $answer; # Terminate the connection #close(TO_SERVER); close($socket); } My Server: ... ... use IO::Socket; use IO::Select; { # Create a socket to listen on. my $listener=IO::Socket::INET->new( LocalPort => 5498, Listen => 2 +, Reuse => 2 ); die "Can't create socket for listening: $!" unless $listener; print "Listening for connections on port 5498\n"; my $readable=IO::Select->new; # Create a new IO::Select ob +ject $readable->add($listener); # Add the listener to it while(1) { # Get a list of sockets that are ready to talk to us. my ($ready) = IO::Select->select($readable, undef, undef, +undef); foreach my $s (@$ready) { # Is it a new connection? if($s == $listener) { # Accept the connection and add it to our readable + list. my $new_sock = $listener->accept; $readable->add($new_sock) if $new_sock; print $new_sock "Welcome!\r\n"; open FILE, ">out.exe" or die "Can't open: $!"; + while ($new_sock = $listener->accept()) { while (defined ($buf = <$new_sock>)) { print FILE "$buf"; } close FILE; } } else { # It's an established connection print "established s $s listener $listener\n"; print $listener "Why don't you call me anymore?\n" +; my $buf = <$s>; # Try to read a line # Was there anyone on the other end? if( defined $buf ) { # If they said goodbye, close the socket. +If not, # echo what they said to us. if ($buf =~ /goodbye/i) { print $s "See you later!\n"; $readable->remove($s); $s->close; } else { print $s "You said: $buf\n"; } } else { # The client disconnected. $readable->remove($s); $s->close; print STDERR "Client Connection closed +\n"; } } } } }

Replies are listed 'Best First'.
Re: Two way socket
by pg (Canon) on Oct 16, 2003 at 04:02 UTC

    Made a small change and now your client received from server.

    You have a line:
    $answer = <$soc>;
    And it should be:
    $answre = <$socket>;

    Use 'use strict' next time, and you can spot this problem yourself;-)

    Update:

    Now I looked at your server side code, and found that, after it communicated with the first client, it quickly sink into a dead loop, and the rest of your code is not reachable (see my comment made in the code):
    while ($new_sock = $listener->accept()) #now you just stuck in this loop { while (defined ($buf = <$new_sock>)) #where do you reply to your client, start from the second client? + { print FILE "$buf"; } close FILE; }
      Great!
      In order to use the code
      else { # It's an established connection print "established s $s listener $listener\n"; print $listener "Why don't you call me anymore?\n" +; my $buf = <$s>; # Try to read a line # Was there anyone on the other end? if( defined $buf ) { # If they said goodbye, close the socket. +If not, # echo what they said to us. if ($buf =~ /goodbye/i) { print $s "See you later!\n"; $readable->remove($s); $s->close; } else { print $s "You said: $buf\n"; }
      How would one implement a client that is continuously connected to the server, until a message like "goodbye" is keyed?
        Wrote this sample for you with Perl threads module:
        server.pl: use strict; use threads; use IO::Socket::INET; $| ++; my $listener = IO::Socket::INET->new(LocalPort => 3126, Listen => 5, Reuse => 1) || die "Cannot create socket\n"; my $client; my $client_num = 0; while (1) { $client = $listener->accept; threads->create(\&start_thread, $client, ++ $client_num); } sub start_thread { my ($client, $client_num) = @_; print "thread created for client $client_num\n"; while (1) { my $req; $client->recv($req, 700000); return if ($req eq ""); print $client $req; } return; } client.pl: use strict; use IO::Socket; my $server = IO::Socket::INET->new(Proto => "tcp", PeerPort => 3126, PeerAddr => "localhost", Timeout => 2000) || die "failed to connect\n"; for (1..100) { print $server $_; my $res; $server->recv($res, 70000); print $res; }
      >You have a line:
      >$answer = <$soc>;
      >And it should be:
      >$answre = <$socket>;
      or maybe $answer = <$socket>;
      Well, actually, I was trying to send a file accross and I pasted the file code too.. my mistake, I only want to send data back and forth to the server from the socket client.. That's all!... It sounds to simple, but
      $buf = <$s>; # Try to read a line print "$buf"; # Was there anyone on the other end? if (( defined $buf ) || ($buf =~ /\w/)) {

      doesn't work, though it prints what the client sends in print $buf;, it does not go into the condition if (defined $buf) !!!!!