sven has asked for the wisdom of the Perl Monks concerning the following question:
I am currently creating a server / multi-client program.
The tool is supposed to query each client about changes in a set of (locally) defined files. The clients are to send the filenames back to the server.
The server should accept the client connection and move the handling to a seperate thread to wait for a new connection. When the user clicks a button, the server will send a command to the client, triggering the local process.
Until now I have only worked withone client, which I block by having it waiting for a queue to conatain something. It would work the same with mulitple clients, but: As I can't be sure how many conenctions I will get, I can't create the queues at program start. ... Well I could create a set of queues larger the my max amount of expected connections, but having dummy queues around isn't very elegant, I believe.
So I have thought about creating the queues after connection of a client and giving it a name like: $restque1 , $restque2, .. I tried doing so with ${restque."$i"}... where $i is the no of connection. But that doesn't work. It gives me an error: Can't declare scalar dereference in "our" at ISIS-OTN.pl line 905, near "} ="
Any help on how to set the threads to sleep and wake them on a button click?
My code looks like this:and a snippet from the other connection manager:sub PortListener { ########################### # Listening and monitoring Client connections # ########################### my $Thread; my $client_name; my $lsn = new IO::Socket::INET(Listen => 1, LocalPort => $port); my $sel = new IO::Select($lsn); my $j; while(my @ready = $sel->can_read) { # as long a +s we can read from foreach my $fh (@ready) { if($fh == $lsn) { # Create a new socket my ($new, $c_addr) = $lsn->accept; $sel->add($new); my ($client_port, $client_ip) = sockaddr_in($c_addr); my $client_ipnum = inet_ntoa($client_ip); my $i; for $i ( 0 .. $#HostList ) { if ($client_ipnum eq $HostList[$i][1]){ $client_name = $HostList[$i][0]; $HostList[$i][2] = 1; my $dummy_name = "HostConn_$i"; $main->$dummy_name->Text("connected"); $main->$dummy_name->Change( -foreground => [ 0 +, 255, 0 ] ); $main->$dummy_name->InvalidateRect(1); $j = $i; last; } } print "got a connection from: $client_name [$client_ip +num]\n"; if ($client_name eq "Win1") { my $Thread = threads->create( "nautserver", $new); + #start the echo-server as a seperate thread } else { my $Thread = threads->create( "restoreserver", $ne +w, $j); #start the echo-server as a seperate thread our ${restque."$j"} = Thread::Queue->new; } #$Thread->detach(); } else { $sel->remove($fh); my $client_ip = IO::Socket::INET::peeraddr($fh); my $client_ipnum = inet_ntoa($client_ip); print "$client_ipnum resigned \n"; STDOUT->autoflush(1); my $i; for $i ( 0 .. $#HostList ) { if ($client_ipnum eq $HostList[$i][1]){ $client_name = $HostList[$i][0]; $HostList[$i][2] = 0; my $dummy_name = "HostConn_$i"; $main->$dummy_name->Text("disconnected"); $main->$dummy_name->Change( -foreground => [ 2 +55, 0, 0 ] ); $main->$dummy_name->InvalidateRect(1); last; } } if ($client_name eq "Win1") { $main->NautActualDisp->Text("connecting ..."); $run->RunNautActualDisp->Text("connecting ..."); } $fh->close; $go->enqueue("2"); # This tells our nautserver that + it should terminate, as we will reopen a new socket } } } } sub restoreserver{ my $session = $_[0]; my $hostno = $_[1]; print "Server for host number $hostno started\n"; STDOUT->autoflush(1); while(1) { # keep looping for ever print "waiting for button\n"; my $queuedvar = ${restque."$hostno"}->dequeue; # sleep unti +l something is in the queue print "Button clicked"; # or do something useful later } }
Thanks a billion for your help.while(1) { # keep looping for ever my $queuedvar = $go->dequeue; # sleep until something is in + the queue if ($queuedvar eq "2") { # if it's a 2 terminate last; } # else go on if ($use_startstop == 1) { $startstoppdu = "True"; } elsif ($use_startstop == 0) { $startstoppdu = "False"; } $send_data = "PUT:" . $nautilus_auto . ":" . $startstoppdu +; $session->send($send_data); $session->recv($received_data,10000); my @data = split(/:/,$received_data); $nautilus_win=$data[1]; $startstoppdu = $data[2]; if ($startstoppdu eq "True") { $use_startstop = 1; } elsif ($startstoppdu eq "False") { $use_startstop = 0; } }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Creating queues for multiple threads on connection of TCP client
by BrowserUk (Patriarch) on Sep 02, 2009 at 09:00 UTC |