Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You need to share <code>$clients</code> via <code>share</code> from <a href="http://perldoc.perl.org/threads/shared.html" rel="nofollow noreferrer"><code>threads::shared</code></a>:</p> <pre><code>my $clients = &amp;share({}); </code></pre> <p>The old-fashioned syntax is due to a documented issue with Perl’s prototypes. If you have <a href="https://perldoc.perl.org/perl589delta.html" rel="nofollow noreferrer">at least Perl 5.8.9</a>, use the nicer</p> <pre><code>my $clients = shared_clone({}); </code></pre> <p>instead.</p> <p>You also want to protect <code>$clients</code> with a lock, <em>e.g.</em>,</p> <pre><code>my $clients_lock : shared; { lock $clients_lock; $clients-&gt;{time()} = fileno $connection; } </code></pre> <p>Finally, because <code>IO::Socket::INET</code> instances are Perl typeglobs, you can’t share them, so instead add their socket descriptors (from <a href="http://perldoc.perl.org/functions/fileno.html" rel="nofollow noreferrer"><code>fileno</code></a>) to <code>$clients</code> and then <code>fdopen</code> the socket when necessary with</p> <pre><code>open my $fh, "&gt;&amp;=", $sockdesc or warn ... </code></pre> <p>The program below repeats inbound data to the other connected sockets:</p> <pre><code>#!/usr/bin/perl use strict; use IO::Socket; use threads; use threads::shared; use Thread::Queue; # init my $clients = &amp;share({}); my $clients_lock : shared; my $queue = Thread::Queue-&gt;new; # thread that monitors threads-&gt;create("monitor"); # create the listen socket my $port = 12345; my $listenSocket = IO::Socket::INET-&gt;new( LocalPort =&gt; $port, Listen =&gt; 10, Proto =&gt; 'tcp', Reuse =&gt; 1 ); # make sure we are bound to the port die "Can't create a listening socket: $@" unless $listenSocket; print "Server ready. Waiting for connections on $port ... \n"; # wait for connections at the accept call while (my $connection = $listenSocket-&gt;accept) { # set client socket to non blocking my $nonblocking = 1; ioctl($connection, 0x8004667e, \\$nonblocking); # autoflush $connection-&gt;autoflush(1); # debug print "Accepted new connection\n"; # add to list { lock $clients_lock; $clients-&gt;{time()} = fileno $connection; } # start new thread and listen on the socket threads-&gt;create("readData", $connection); } sub readData { # socket parameter my ($client) = @_; # read client while (&lt;$client&gt;) { chomp; $queue-&gt;enqueue($_); } close $client; } sub monitor { # endless loop while (1) { # loop while there is something in the queue while ($queue-&gt;pending) { # get data from a queue my $data = $queue-&gt;dequeue; # loop all sockets { lock $clients_lock; while ( my ($key, $value) = each(%$clients) ) { # send to socket if (open my $fh, "&gt;&amp;=", $value) { print $fh "$data\n"; } else { warn "$0: fdopen $value: $!"; } } } } # wait 0,25 seconds select(undef, undef, undef, 0.25); } } close $listenSocket; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload