#!/usr/bin/perl use warnings; use strict; use IO::Socket; use threads; use threads::shared; $|++; print "$$ Server started\n";; # do a "top -p -H $$" to monitor server threads my $buf2; my $SyncID; my $SyncHeader; my $UnitID; our @clients : shared; @clients = (); our $k; our $m; our $n; our $p; our $dup=0; our $sel_cli2; my @Mdevices; my $ref; my $peerC = 1; #### my $server = new IO::Socket::INET( Timeout => 500, Proto => "tcp", LocalPort => 8000, Reuse => 1, Listen => 5 ); my $num_of_client = -1; while (1) { my $client; do { $client = $server->accept; } until ( defined($client) ); my $peerhost = $client->peerhost(); $peerC = $peerhost; if ($peerC ne '127.0.0.1') { my $template = 'vvV'; read $client, my $sync_packet,8 or die "Couldn't read from client: $!"; ($SyncHeader,$SyncID,$UnitID) = unpack $template, $sync_packet; print "accepted a client $client, $UnitID, $peerhost, id = ", ++$num_of_client, "\n"; } else { $UnitID = 888; print "accepted a client $client, $peerhost, id = ", ++$num_of_client, "\n"; } my $fileno = fileno $client; push (@clients, $fileno); for ($k=0; $k<=$#Mdevices; $k++) { if ($Mdevices[$k][0] eq $UnitID) # searching existing UnitID in Array { $dup =1; print "Duplicate found $Mdevices[$k][0] |"; $Mdevices[$k][1] = $fileno; # update existing UnitID with new fileno } } if ($dup eq 1) { print "NO changes |"; $dup = 0; } else { for ($n=0; $n<=$#Mdevices; $n++) # chech if exist some entry with old fileno, should be deleted { if ($Mdevices[$n][1] eq $fileno) { print "deleting |"; $Mdevices[$n][1] = 0; # set old entry's fileno to 0 to not interfere. } } push (@Mdevices, [$UnitID, $fileno]); # add new device with fileno to array } use Data::Dumper; print Dumper(\@Mdevices); #spawn a thread here for each client my $thr = threads->new( \&processit, $client, $fileno, $peerhost )->detach(); } #### sub processit { my ($lclient,$lfileno,$lpeer) = @_; #local client my $sel_cli_id = $num_of_client; if($lclient->connected){ while(<$lclient>) { if ($peerC eq '127.0.0.1') # tcp client from localhost is used just to send commands to other connected clients { my(@comm) = split(/:/, $_); my $sel_clix = $comm[0]; my $commandC = $comm[1]; for ($p=0; $p<=$#Mdevices; $p++) { if ($Mdevices[$p][0] eq $sel_clix) { $sel_cli2 = $Mdevices[$p][1]; } } foreach my $fn ($sel_cli2) { if ($sel_cli2) { open my $fh, ">&=$fn" or warn $! and die; print "\n $lclient $sel_cli2 Command sent to: $sel_clix Command: $commandC"; print $fh "$commandC\n" } else { print "\n $lclient Device: $sel_clix NOT avaiable to receive command\n"; } } } else { print "COMMAND RESPONCE: $_"; } } } #close filehandle before detached thread dies out close( $lclient); #remove multi-echo-clients from echo list @clients = grep {$_ !~ $lfileno} @clients; }