Advertisement
saltycracker

selectServerAndClient7.pl

Apr 23rd, 2020
1,067
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 4.89 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 Getopt::Long;
  9. use IO::Select;
  10. use IO::Socket::INET;
  11.  
  12. sub box_string {
  13.     my ($str) = @_;
  14.     my $line = sprintf "|-%s-|", '-' 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 options '$!'";
  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.     LocalPort => $port,
  41.     LocalAddr => $addr,
  42.     Listen => 5,
  43.     ReuseAddr => SO_REUSEADDR,
  44.     Proto => 'tcp'
  45. ) || die "Invalid server '$!'";
  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.             $sel->add([scalar($socket->accept), "Client Socket"]);
  61.             say "Server accepted new client";
  62.         }else {
  63.             @write_handles = grep {
  64.                 ($_->[0] != $socket) && ($_->[0] != $handle->[0])
  65.             } $sel->can_write(0);
  66.            
  67.             #check filehandle for eof
  68.             do {
  69.                 say "Client: ", $handle->[1], " exited";
  70.                 $sel->remove($handle->[0]);
  71.                 $handle->[0]->close;
  72.                 do {
  73.                     print {$_->[0]} "Client: ", $handle->[1], " exited\r\n";
  74.                     print {$_->[0]} "<<DONE>>\r\n";
  75.                 } for @write_handles;
  76.                 next;
  77.             } if $handle->[0]->eof;
  78.            
  79.             #get the message from filehandle
  80.             my $msg = do {
  81.                 local $/ = "\r\n";
  82.                 my $h = $handle->[0];
  83.                 chomp(my $m = <$h>);
  84.                 $m;
  85.             };
  86.  
  87.             #do something with msg
  88.             if ($msg =~ /m-/) {
  89.                 do {
  90.                     print {$_->[0]} "Client: ", $handle->[1], " sent: $msg\r\n";
  91.                     print {$_->[0]} "<<DONE>>\r\n";
  92.                 } for @write_handles;
  93.                 say "Client: ", $handle->[1], " sent: $msg";
  94.             }elsif ($msg =~ /x-/) {
  95.                 do {
  96.                     print {$_->[0]} "Client: ", $handle->[1], " exited\r\n";
  97.                     print {$_->[0]} "<<DONE>>\r\n";
  98.                 } for @write_handles;
  99.                 say "Client: ", $handle->[1], " exited";
  100.                 $sel->remove($handle->[0]);
  101.                 $handle->[0]->close;
  102.             }elsif ($msg =~ /t-/) {
  103.                 $handle->[1] = $msg;
  104.                 do {
  105.                     print {$_->[0]} "Client: ", $handle->[1], " name change\r\n";
  106.                     print {$_->[0]} "<<DONE>>\r\n";
  107.                 } for @write_handles;
  108.                 say "Client: ", $handle->[1], " name change";
  109.             }elsif ($msg =~ /h-/) {
  110.                 print {$handle->[0]} "x- to exit\r\n";
  111.                 print {$handle->[0]} "l- list active users\r\n";
  112.                 print {$handle->[0]} "m-'message' send message to all users\r\n";
  113.                 print {$handle->[0]} "t-'UserName' to change user name\r\n";
  114.                 print {$handle->[0]} "h- display this help message\r\n";
  115.                 print {$handle->[0]} "<<DONE>>\r\n";
  116.                 say "Client: ", $handle->[1], " requested help";
  117.             }elsif ($msg =~ /l-/) {
  118.                 do {
  119.                     print {$handle->[0]} "Client: ", $_->[1], "\r\n";
  120.                 } for @write_handles;
  121.                 print {$handle->[0]} "<<DONE>>\r\n";       
  122.                 say "Client: ", $handle->[1], " listing";
  123.             }else {
  124.                 say "Client: ", $handle->[1], " unknown request: $msg";
  125.             }
  126.         }
  127.     }
  128. }
  129.  
  130. $socket->close;
  131.  
  132. exit(0);
  133.  
  134. ##############################################################
  135.  
  136. #! /usr/bin/env perl
  137.  
  138. use warnings;
  139. use strict;
  140. use utf8;
  141. use feature qw<say>;
  142.  
  143. use Getopt::Long;
  144. use IO::Select;
  145. use IO::Socket::INET;
  146.  
  147. sub box_string {
  148.     my ($str) = @_;
  149.     my $line = sprintf "|-%s-|", '-' 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 options '$!'";
  160.  
  161. do {
  162.     say "Must call $0 with --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 "Client failed '$!'";
  180.  
  181. box_string("Client($user) active: $addr:($port)");
  182.  
  183. say "Client running....";
  184.  
  185. my $sel = IO::Select->new;
  186.  
  187. $sel->add(\*STDIN);
  188. $sel->add($client);
  189.  
  190. print {$client} "t-$user\r\n";
  191.  
  192. my @read_handles;
  193.  
  194. while (@read_handles = $sel->can_read) {
  195.     for my $handle (@read_handles) {
  196.         if ($handle == $client) {
  197.             do {
  198.                 say "Connection problems! Exiting";
  199.                 $client->close;
  200.                 exit(1);
  201.             } if $client->eof;
  202.  
  203.             while (<$client>) {
  204.             local $/ = "\r\n";
  205.             last if /<<DONE>>/;
  206.             chomp;    
  207.             say "$_";
  208.             }
  209.         }else {
  210.             chomp(my $msg = <STDIN>);
  211.             do {
  212.                 print {$client} "$msg\r\n";
  213.                 say "Exiting client";
  214.                 $client->close;
  215.                 exit (0);
  216.             } if $msg =~ /x-/;
  217.             print {$client} "$msg\r\n";
  218.         }
  219.     }
  220. }
  221.  
  222. exit (0);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement