Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #! /usr/bin/env perl
- use warnings;
- use strict;
- use utf8;
- use feature qw<say>;
- use IO::Socket::INET;
- use IO::Select;
- use Getopt::Long;
- sub box_string {
- my ($str) = @_;
- my $line = "|--".'-' x length($str)."--|";
- say $line;
- say "|->", $str, "<-|";
- say $line;
- }
- GetOptions (
- "Port|P=i" => \my $port,
- "Addr|A=s" => \my $addr
- ) || die "Invalid command line '$!'";
- do {
- say "Must call $0 --Port|P=1234 --Addr|A=127.0.0.1";
- exit (1);
- } unless $port && $addr;
- box_string("Server on: $addr:($port)");
- print "Start server(y/n)? ";
- do {
- say "Exiting $0";
- exit (0);
- } unless <STDIN> =~ /^y$/;
- my $socket = IO::Socket::INET->new(
- LocalAddr => $addr,
- LocalPort => $port,
- Listen => 5,
- Proto => 'tcp',
- ReuseAddr => SO_REUSEADDR
- ) || die "Invalid socket '$!'";
- box_string("Server active on: $addr:($port)");
- say "Server running....";
- my $sel = IO::Select->new;
- $sel->add([$socket, "Server Socket"]);
- my @read_handles;
- my @write_handles;
- while (@read_handles = $sel->can_read) {
- for my $handle (@read_handles) {
- if ($handle->[0] == $socket) {
- $sel->add([scalar($socket->accept), "Client Socket"]);
- say "Accepted new client";
- }else {
- @write_handles = grep {
- ($_->[0] != $socket) && ($_->[0] != $handle->[0])
- } $sel->can_write(0);
- do {
- say "Connection problems with ", $handle->[1], " exiting";
- do {
- print {$_->[0]} "Client: ", $handle->[1], " exited\r\n";
- print {$_->[0]} "<<DONE>>\r\n";
- } for @write_handles;
- $sel->remove($handle->[0]);
- $handle->[0]->close;
- next;
- } if $handle->[0]->eof;
- my $msg = do {
- local $/ = "\r\n";
- my $h = $handle->[0];
- chomp(my $m = <$h>);
- $m;
- };
- if ($msg =~ /h-/) {
- print {$handle->[0]} "h- display help message\r\n";
- print {$handle->[0]} "m-(Message) send message\r\n";
- print {$handle->[0]} "l- list users\r\n";
- print {$handle->[0]} "t-(UserName) change user name\r\n";
- print {$handle->[0]} "x- exit\r\n";
- print {$handle->[0]} "<<DONE>>\r\n";
- }elsif ($msg =~ /m-/) {
- say "Client: ", $handle->[1], " sent:$msg";
- do {
- print {$_->[0]} "Client: ", $handle->[1], " sent:$msg\r\n";
- print {$_->[0]} "<<DONE>>\r\n";
- } for @write_handles;
- }elsif ($msg =~ /l-/) {
- say "Client: ", $handle->[1], " user listing";
- do {
- print {$handle->[0]} "Client: ", $_->[1], "\r\n";
- } for @write_handles;
- print {$handle->[0]} "<<DONE>>\r\n";
- }elsif ($msg =~ /t-/) {
- $handle->[1] = $msg;
- say "Client: ", $handle->[1], " changed names";
- do {
- print {$_->[0]} "Client: ", $handle->[1], " changed names\r\n";
- print {$_->[0]} "<<DONE>>\r\n";
- } for @write_handles;
- }elsif ($msg =~ /x-/) {
- say "Client: ", $handle->[1], " exited";
- do {
- print {$_->[0]} "Client: ", $handle->[1], " exited\r\n";
- print {$_->[0]} "<<DONE>>\r\n";
- } for @write_handles;
- $sel->remove($handle->[0]);
- $handle->[0]->close;
- }else {
- say "Client: ", $handle->[1], " sent unknown msg: $msg";
- }
- }
- }
- }
- $socket->close;
- exit(0);
- ###client
- #! /usr/bin/env perl
- use warnings;
- use strict;
- use utf8;
- use feature qw<say>;
- use IO::Socket::INET;
- use IO::Select;
- use Getopt::Long;
- sub box_string {
- my ($str) = @_;
- my $line = "|--".'-' x length($str)."--|";
- say $line;
- say "|->", $str, "<-|";
- say $line;
- }
- GetOptions (
- "Port|P=i" => \my $port,
- "Addr|A=s" => \my $addr,
- "User|U=s" => \my $user
- ) || die "Invalid command line '$!'";
- do {
- say "Must call $0 --Port|P=1234 --Addr|A=127.0.0.1 --User|U=UserName";
- exit (1);
- } unless $port && $addr && $user;
- box_string("Client($user) on: $addr:($port)");
- print "Start client(y/n)? ";
- do {
- say "Exiting $0";
- exit (0);
- } unless <STDIN> =~ /^y$/;
- my $client = IO::Socket::INET->new(
- PeerAddr => $addr,
- PeerPort => $port,
- Proto => 'tcp'
- ) || die "Invalid client '$!'";
- box_string("Client($user) active on: $addr:($port)");
- say "Client running....";
- my $sel = IO::Select->new;
- $sel->add(\*STDIN);
- $sel->add($client);
- print {$client} "t-$user\r\n";
- my @read_handles;
- while (@read_handles = $sel->can_read) {
- for my $handle (@read_handles) {
- if ($handle == $client) {
- do {
- say "Connection problems... Exiting $0";
- exit (3);
- } if $client->eof;
- {
- local $/ = "\r\n";
- while (<$client>) {
- chomp;
- last if /<<DONE>>/;
- print "$_\n";
- }
- }
- }else {
- chomp(my $msg = <STDIN>);
- do {
- say "Exiting $0";
- print {$client} "$msg\r\n";
- exit (0);
- } if $msg =~ /x-/;
- print {$client} "$msg\r\n";
- }
- }
- }
- $client->close;
- exit(0);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement