Fellow Monks,

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:
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 } }
and a snippet from the other connection manager:
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; } }
Thanks a billion for your help.
Sven

In reply to Creating queues for multiple threads on connection of TCP client by sven

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.