# $readable_handles = Select::IO->new();
# $readable_handles->add($server_sock);
$select_object = Select::IO->new($server_sock);
####
#while(1){
while(@readables = $select_object->can_read){
####
# if( $sck eq $sock ){}
if( $sck == $sock ){}
####
else {
# store message in queue
push( @clients , $text[1] );
#--> --^
# further down ...
print Dumper(\@clients);
$trans = "OK";
$client_data = &send($trans);
print "Second send: ".$client_data."\n";
}
} # End of if ($text[0] eq "NICK")
elsif ($text[0] eq "MSG") {
if (length($text[1]) > MAXBYTES) {
$trans = "".$error." Please remember that message limit is ".MAXBYTES."";
$client_data = &send($trans);
print "In case of message over ".MAXBYTES." send: ".$client_data."\n";
}
else {
print "Second receive: ".$text[1]."\n";
print "This is \$sock: ".$sock."\n";
# Get all client(s) socket(s)
my @sockets = $readable_handles->can_write();
#my $count = $readable_handles->count();
# store messages in hash ?
# for as many sockets that are readable, take the message
# with the index of this this number, from the message
# queue and replace the current hashed socket queue with
# it.
# that is, if 5 clients then each client will continue to
# recieve the fifth messages from the message queue.
# or at least teh log will only record that, depending on
# whr STDOUT
for ($_ = 0; $_ < @sockets; $_++) {
$hash{$sock} = $clients[$_];
}
# or
$hash{$sock} =
$clients[ scalar @{$select_object->can_write()} ]
####
#!/usr/bin/perl
use utf8;
use strict;
use warnings;
use IO::Select;
use Data::Dumper;
use IO::Socket::INET; # Non-blocking I/O concept.
use constant ARGUMENTS => scalar 1;
use constant NICKNAME => scalar 12;
use constant MAXBYTES => scalar 255;
# flush memory after every initialization
$| = 1;
my $error = "ERROR";
my %hash = (); # global variable
my ( $client_data , $buf , $sock , $msg , $new_sock , $trans , $readable_handles , $client , $port );
unless (@ARGV == ARGUMENTS) {
print "\nPlease only ARGUMENTS input!\n";
print "Correct Syntax: perl $0 IP:PORT (e.g. 127.0.0.1:5000)\n";
exit();
}
# User message IP:PORT
( my ( $inputip, $inputport ) =
( $ARGV[0] =~ m/^( # $1 $inputip
(?: #non-capturing
\d{1,3}\. #1-3 digits followed by stop
){3} # x3
\d{1,3} #last 1-3 digit of ip address
)
: # colon
(\d+) # $2 $inputport
$/x ) ); # endmatch
print "::$inputip:-:$inputport:\n";
my $server_sock = IO::Socket::INET->new(
LocalAddr => $inputip,
LocalPort => $inputport,
Proto => 'tcp',
Listen => SOMAXCONN,
Reuse => 1
) or die "Could not connect: $!";
print "\n[Server $0 accepting clients at IP: $inputip and PORT: $inputport.]\n";
# $readable_handles = IO::Select->new();
my $select_object = IO::Select->new($server_sock);
while (1) {
my @readables = IO::Select->select($select_object, undef, undef, 0) ;
foreach $sock ( @{ $readables[0] } ) {
# Check if sock is the same with server (e.g. 5000)
# if same (new client) accept client socket
if ($sock == $server_sock) {
$new_sock = $sock->accept()
or die sprintf "ERROR (%d)(%s)(%d)(%s)", $!,$!,$^E,$^E;
$select_object->add($new_sock);
$trans = "Hello version";
print { $new_sock } utf8::encode( $trans );
print "First send: $trans\n";
}else{
# read from socket input
$buf = <$sock>;
my ($msg , $port) = receive($buf);
my @text = split(/ / , $msg , 2); # LIMIT = 2 Only the first two gaps split
#print Dumper(@text);
if ($text[0] eq "NICK") {
$hash{$port} = $text[1];
print Dumper(\%hash);
#print Dumper(\@names);
$trans = "OK";
print { $sock } utf8::encode( $trans );
print "Second send: $trans\n";
}elsif ($text[0] eq "MSG") {
print "Second receive: ".$text[1]."\n";
# Get all client(s) socket(s)
#my @names = values %hash;
my @sockets = $select_object->can_write();
# possible problem ?
# none writeable - only 'select'ed readables writeable ??
# (my $new_readable) = IO::Select->select($select_object, undef, undef, 0);
#print Dumper(\@sockets);
# Send the same message to client(s)
foreach my $sck (@sockets) {
my $final = "$text[0] $hash{$port} $text[1] \n";
utf8::encode($final);
print { $sck } $final;
print "Third send: $final";
#print STDOUT "The following data send to Client(s): (\ ".$buf." \)\n";
}
}else{
print "Closing client!\n";
# when the client disconnects
delete $hash{$port};
$select_object->remove($sock);
close($sock);
}
} # End of else condition ($sock == $server_sock)
} # End of foreach $sock @readables
} # End of While (1)
print "Terminating Server\n";
close $server_sock;
getc();
sub send {
utf8::encode( $_[0] );
print { $new_sock } $_[0],"\n";
# chomp ($_[0]); # ? chomp encoded line?
#print "The following data send to Clients: (\ ".$_[0]." \)\n";
#$client_sock->send($client_packet,MAXBYTES);
return $_[0];
}
sub receive {
#$new_sock->recv($client_data,MAXBYTES);
my $datarecieved = utf8::decode($_[0]);
# assign $1 to $shortdata may need correcting.
my( $shortdata ) = ( m/^(.{0,20})/ =~ $datarecieved );
my( $phost, $pport ) = ( $new_sock->peerhost(), $new_sock->peerport() );
my $fromhostport = "From host: $phost and port: $pport";
print "This:$shortdata\n$fromhostport\n";
return( $datarecieved, $pport );
#(?) should not get here...
utf8::encode (qq{ $error, \n } );
$server_sock->send($error);
print "Invalid client: $phost : terminating!\n";
$select_object->remove($sock);
close($sock);
}