The main application for network chat in Perl

I am trying to write a basic web chat application in Perl for training. Currently, I have a server and client program that work almost exactly the way I want. Several clients can connect to the server and send messages to and from it. However, I’m not quite sure how to go about sending messages from one client to another, and I would appreciate the push in the right direction. Here is the code that I still have, thoughts?

Note. This is my first attempt to use the network or use Perl for a proper project, so any other guide to writing it will also be appreciated.

chat_server.pl

#!/usr/bin/perl -w # chat_server.pl use strict; use IO::Socket::INET; my $port = shift or die "Port required!\n"; my $socket = IO::Socket::INET->new( LocalPort => $port, Proto => 'tcp', Listen => SOMAXCONN ) or die "Can't create socket: $!!\n"; my $child; print "Listening for clients on $port...\n"; REQUEST: while(my $client = $socket->accept) { my $addr = gethostbyaddr($client->peeraddr, AF_INET); my $port = $client->peerport; if($child = fork) { print "New connection from $addr:$port\n"; close $client; next REQUEST; } die "fork failed!\n" unless defined $child; while (<$client>) { print "[$addr:$port] says: $_"; print $client "[$addr:$port] says: $_"; } } close $socket; 

chat_client.pl

 #!/usr/bin/perl -w # chat_client.pl use strict; use IO::Socket::INET; my $port = shift or die "No port\n"; my $server = shift or die "No server\n"; my $client_socket = IO::Socket::INET->new( PeerPort => $port, PeerAddr => $server, Proto => 'tcp' ) or die "Can't create send socket: $!!\n"; my $child; if($child = fork) { while(1) { sleep(1); print scalar <$client_socket>; } } die "fork failed!\n" unless defined $child; print "Connected to $server:$port!\n"; do { print "> "; print $client_socket $_ if defined $_; } while(<STDIN>); print "Closing connection"; close $client_socket; 
+5
source share
1 answer

One client per server is not too complicated - what you do with your code is efficient - creating relationships from 1 to 1. Your fork ed server works exclusively with your client.

In order to get information for distribution (through the server) between several clients, you will have to get a little complicated - because you have separate processes, now these processes must interact with each other. This is a pretty big question that there is a whole segment of perl: perlipc .

This will significantly increase the complexity of your code because you are moving to a one-to-many relationship in your messages, and they will all occur asynchronously.

Socket-based communication is a form of interprocess communication (IPC), and you already do it. But your "getcha" here is that you go from 1 to 1 comm. Up to 1 to many. You should be able to broadcast, and this method of communication does not support this particularly well.

What I would like to suggest, look at IO::Pipe - here is an example code: How to extract data from Parallel :: ForkManager in perl

Then use IO::Select and can_read to asynchronously decide if there is any data in the pipe. You will probably need an array of pipes β€” one for each customer β€” otherwise you may be matched with matching materials.

eg:.

(From IO::Pipe doc page:

  my $pipe = IO::Pipe->new(); if($pid = fork()) { # Parent $pipe->reader(); while(<$pipe>) { ... } } elsif(defined $pid) { # Child $pipe->writer(); print $pipe ... } 

Unfortunately, there is little information here: your pipes will be created by the forking process, but this, in turn, means that you need to figure out how to process the pipe array and check if they are available.

This means that you can no longer sit in the while with accepting sockets, which is blocked, so you will have message queues until the other client connects (which is really not the way you want). Therefore, you will also need to use select again to check if there is something ready for accept .

+1
source

Source: https://habr.com/ru/post/1232061/


All Articles