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

the next code connect one server and one client, the connection works and the client already send messages to server. Now i need to replicate the messages to other clients conneced. if anyone correct the code for me... i tks a lot. Client.
#! /usr/bin/perl -w # client0.pl use strict; use Socket; my $host = shift || 'localhost'; my $port = shift || 7890; my $proto = getprotobyname('tcp'); my $line; my $connection = "0"; my $iaddr = inet_aton($host); my $paddr = sockaddr_in($port, $iaddr); socket(SOCKET, PF_INET, SOCK_STREAM, $proto) or die "socket: $!"; my $old_fh = select(SOCKET); $| = 1; select($old_fh); connect(SOCKET, $paddr) or die "connect: $!"; print "Cliente Conectado \n"; while ($connection == 0) { $line = <SOCKET>; chomp ($line); if ($line eq "OK") { my $texto; $texto=<STDIN>; print SOCKET "$texto\n"; print "Passo a citar:\n $texto \n"; print SOCKET "OK\n"; } } close SOCKET or die "close: $!"; print "\n --Client has disconnected-- \n";
Server
#!/usr/bin/perl -w # server0.pl use strict; use Socket; my $port = shift || 7890; my $proto = getprotobyname('tcp'); socket( SERVER, PF_INET, SOCK_STREAM, $proto ) or die "socket: $!"; setsockopt( SERVER, SOL_SOCKET, SO_REUSEADDR, 1 ) or die "setsock: $!" +; my $paddr = sockaddr_in( $port, INADDR_ANY ); bind( SERVER, $paddr ) or die "bind: $!"; listen( SERVER, SOMAXCONN ) or die "listen: $!"; print "SERVER Inicializado na porta $port\n"; my $client_addr; my $connection="0"; my $line; while ( $client_addr = accept( CLIENT, SERVER ) ) { my ( $client_port, $client_ip ) = sockaddr_in($client_addr); my $client_ipnum = inet_ntoa($client_ip); my $client_host = gethostbyaddr( $client_ip, AF_INET ); print "Nova coneccao establecida:\n"; print "Conecção do Cliente $client_host", " [$client_ipnum]\n"; my $old_fh = select(CLIENT); $| = 1; select($old_fh); print CLIENT "OK\n"; while ($connection eq "0") { $line = <CLIENT>; print $line; print CLIENT $line; } }
tks for the help

Replies are listed 'Best First'.
Re: perl chat
by pc88mxer (Vicar) on Apr 24, 2008 at 16:44 UTC
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: perl chat
by zentara (Cardinal) on Apr 24, 2008 at 19:01 UTC
    ks but i realy need this code...

    What you are looking for is called a "multi-echo chat server". The basic thing to do, is push all of your connected clients into an array, then after you receive an input, print to every socket filehandle in the array, instead of just the sending client. There is alot of housekeeping to take care of, and your code makes it difficult to deal with the socket filehandle names. You also need a client that can send and receive at the same time. Here is a simple example of both, but if you need to use your pure sockets code, read the perl examples at perl sockets

    #!/usr/bin/perl # server multi-echo use IO::Socket; use IO::Select; my @sockets; my $machine_addr = 'localhost'; $main_sock = new IO::Socket::INET(LocalAddr=>$machine_addr, LocalPort=>1200, Proto=>'tcp', Listen=>3, Reuse=>1, ); die "Could not connect: $!" unless $main_sock; print "Starting Server\n"; $readable_handles = new IO::Select(); $readable_handles->add($main_sock); while (1) { ($new_readable) = IO::Select->select($readable_handles, undef, undef +, 0); foreach $sock (@$new_readable) { if ($sock == $main_sock) { $new_sock = $sock->accept(); $readable_handles->add($new_sock); } else { $buf = <$sock>; if ($buf) { print "$buf\n"; my @sockets = $readable_handles->can_write(); #print $sock "You sent $buf\n"; foreach my $sck(@sockets){print $sck "$buf\n";} } else { $readable_handles->remove($sock); close($sock); } } } } print "Terminating Server\n"; close $main_sock; getc();
    #!/usr/bin/perl -w # interactive client use strict; use IO::Socket; my ( $host, $port, $kidpid, $handle, $line ); ( $host, $port ) = ('localhost',1200); my $name = shift || ''; if($name eq ''){print "What's your name?\n"} chomp ($name = <>); # create a tcp connection to the specified host and port $handle = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $host, PeerPort => $port ) or die "can't connect to port $port on $host: $!"; $handle->autoflush(1); # so output gets there right away print STDERR "[Connected to $host:$port]\n"; # split the program into two processes, identical twins die "can't fork: $!" unless defined( $kidpid = fork() ); # the if{} block runs only in the parent process if ($kidpid) { # copy the socket to standard output while ( defined( $line = <$handle> ) ) { print STDOUT $line; } kill( "TERM", $kidpid ); # send SIGTERM to child } # the else{} block runs only in the child process else { # copy standard input to the socket while ( defined( $line = <STDIN> ) ) { print $handle "$name->$line"; } }

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum