Advertisement
saltycracker

selectServerAndClient3.pl

May 20th, 2020
353
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 4.78 KB | None | 0 0
  1. #! /usr/bin/env perl
  2.  
  3. use warnings;
  4. use strict;
  5. use utf8;
  6. use feature qw<say>;
  7.  
  8. use IO::Socket::INET;
  9. use IO::Select;
  10. use Getopt::Long;
  11.  
  12. sub box_string {
  13.     my ($str) = @_;
  14.     my $line = "|--".'-' x length($str)."--|";
  15.     say $line;
  16.     say "|->", $str, "<-|";
  17.     say $line;
  18. }
  19.  
  20. GetOptions (
  21.     "Port|P=i" => \my $port,
  22.     "Addr|A=s" => \my $addr
  23.     ) || die "Invalid command line '$!'";
  24.  
  25. do {
  26.     say "Must call $0 --Port|P=1234 --Addr|A=127.0.0.1";
  27.     exit (1);
  28. } unless $port && $addr;
  29.  
  30. box_string("Server on: $addr:($port)");
  31.  
  32. print "Start server(y/n)? ";
  33.  
  34. do {
  35.     say "Exiting $0";
  36.     exit (0);
  37. } unless <STDIN> =~ /^y$/;
  38.  
  39. my $socket = IO::Socket::INET->new(
  40.     LocalAddr => $addr,
  41.     LocalPort => $port,
  42.     Listen => 5,
  43.     Proto => 'tcp',
  44.     ReuseAddr => SO_REUSEADDR
  45.     ) || die "Invalid socket '$!'";
  46.  
  47. box_string("Server active on: $addr:($port)");
  48.  
  49. say "Server running....";
  50.  
  51. my $sel = IO::Select->new;
  52. $sel->add([$socket, "Server Socket"]);
  53.  
  54. my @read_handles;
  55. my @write_handles;
  56.  
  57. while (@read_handles = $sel->can_read) {
  58.     for my $handle (@read_handles) {
  59.     if ($handle->[0] == $socket) {
  60.        
  61.         $sel->add([scalar($socket->accept), "Client Socket"]);
  62.         say "Accepted new client";
  63.        
  64.     }else {
  65.  
  66.         @write_handles = grep {
  67.         ($_->[0] != $socket) && ($_->[0] != $handle->[0])
  68.         } $sel->can_write(0);
  69.  
  70.         do {
  71.         say "Connection problems with ", $handle->[1], " exiting";
  72.         do {
  73.             print {$_->[0]} "Client: ", $handle->[1], " exited\r\n";
  74.             print {$_->[0]} "<<DONE>>\r\n";
  75.         } for @write_handles;
  76.         $sel->remove($handle->[0]);
  77.         $handle->[0]->close;
  78.         next;
  79.         } if $handle->[0]->eof;
  80.  
  81.         my $msg = do {
  82.         local $/ = "\r\n";
  83.         my $h = $handle->[0];
  84.         chomp(my $m = <$h>);
  85.         $m;
  86.         };
  87.  
  88.         if ($msg =~ /h-/) {
  89.         print {$handle->[0]} "h- display help message\r\n";
  90.         print {$handle->[0]} "m-(Message) send message\r\n";
  91.         print {$handle->[0]} "l- list users\r\n";
  92.         print {$handle->[0]} "t-(UserName) change user name\r\n";
  93.         print {$handle->[0]} "x- exit\r\n";
  94.         print {$handle->[0]} "<<DONE>>\r\n";
  95.         }elsif ($msg =~ /m-/) {
  96.         say "Client: ", $handle->[1], " sent:$msg";
  97.         do {
  98.             print {$_->[0]} "Client: ", $handle->[1], " sent:$msg\r\n";
  99.             print {$_->[0]} "<<DONE>>\r\n";
  100.         } for @write_handles;
  101.         }elsif ($msg =~ /l-/) {
  102.         say "Client: ", $handle->[1], " user listing";
  103.         do {
  104.             print {$handle->[0]} "Client: ", $_->[1], "\r\n";
  105.         } for @write_handles;
  106.         print {$handle->[0]} "<<DONE>>\r\n";
  107.         }elsif ($msg =~ /t-/) {
  108.         $handle->[1] = $msg;
  109.         say "Client: ", $handle->[1], " changed names";
  110.         do {
  111.             print {$_->[0]} "Client: ", $handle->[1], " changed names\r\n";
  112.             print {$_->[0]} "<<DONE>>\r\n";
  113.         } for @write_handles;
  114.         }elsif ($msg =~ /x-/) {
  115.         say "Client: ", $handle->[1], " exited";
  116.         do {
  117.             print {$_->[0]} "Client: ", $handle->[1], " exited\r\n";
  118.             print {$_->[0]} "<<DONE>>\r\n";
  119.         } for @write_handles;
  120.         $sel->remove($handle->[0]);
  121.         $handle->[0]->close;
  122.         }else {
  123.         say "Client: ", $handle->[1], " sent unknown msg: $msg";
  124.         }
  125.        
  126.     }
  127.     }
  128. }
  129.  
  130. $socket->close;
  131.  
  132. exit(0);
  133.  
  134. ###client
  135.  
  136. #! /usr/bin/env perl
  137.  
  138. use warnings;
  139. use strict;
  140. use utf8;
  141. use feature qw<say>;
  142.  
  143. use IO::Socket::INET;
  144. use IO::Select;
  145. use Getopt::Long;
  146.  
  147. sub box_string {
  148.     my ($str) = @_;
  149.     my $line = "|--".'-' x length($str)."--|";
  150.     say $line;
  151.     say "|->", $str, "<-|";
  152.     say $line;
  153. }
  154.  
  155. GetOptions (
  156.     "Port|P=i" => \my $port,
  157.     "Addr|A=s" => \my $addr,
  158.     "User|U=s" => \my $user
  159.     ) || die "Invalid command line '$!'";
  160.  
  161. do {
  162.     say "Must call $0 --Port|P=1234 --Addr|A=127.0.0.1 --User|U=UserName";
  163.     exit (1);
  164. } unless $port && $addr && $user;
  165.  
  166. box_string("Client($user) on: $addr:($port)");
  167.  
  168. print "Start client(y/n)? ";
  169.  
  170. do {
  171.     say "Exiting $0";
  172.     exit (0);
  173. } unless <STDIN> =~ /^y$/;
  174.  
  175. my $client = IO::Socket::INET->new(
  176.     PeerAddr => $addr,
  177.     PeerPort => $port,
  178.     Proto => 'tcp'
  179.     ) || die "Invalid client '$!'";
  180.  
  181. box_string("Client($user) active on: $addr:($port)");
  182.  
  183. say "Client running....";
  184.  
  185. my $sel = IO::Select->new;
  186. $sel->add(\*STDIN);
  187. $sel->add($client);
  188.  
  189. print {$client} "t-$user\r\n";
  190.  
  191. my @read_handles;
  192.  
  193. while (@read_handles = $sel->can_read) {
  194.     for my $handle (@read_handles) {
  195.     if ($handle == $client) {
  196.  
  197.         do {
  198.         say "Connection problems... Exiting $0";
  199.         exit (3);
  200.         } if $client->eof;
  201.  
  202.         {
  203.         local $/ = "\r\n";
  204.         while (<$client>) {
  205.             chomp;
  206.             last if /<<DONE>>/;
  207.             print "$_\n";
  208.         }
  209.         }
  210.        
  211.     }else {
  212.  
  213.         chomp(my $msg = <STDIN>);
  214.  
  215.         do {
  216.         say "Exiting $0";
  217.         print {$client} "$msg\r\n";
  218.         exit (0);
  219.         } if $msg =~ /x-/;
  220.  
  221.         print {$client} "$msg\r\n";
  222.     }
  223.     }
  224. }
  225.  
  226. $client->close;
  227.  
  228. exit(0);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement