Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: How to serve multiple socket clients Perl

by sundialsvc4 (Abbot)
on Mar 23, 2015 at 14:33 UTC ( [id://1120990]=note: print w/replies, xml ) Need Help??


in reply to How to serve multiple socket clients Perl

You really can’t have “searched the net with no results.”   :-)   There are literally thousands of servers out there which are all implemented in mostly the exact same way:   with a select() loop.   (Many of them are built using existing server-building toolkits, such as the great-many ... say, POE ... that are available for Perl.   (Or, say, Twisted ... every language has several to choose from.)   “Actum Ne Agas:   Do not do a thing already done.™”)

Conceptually speaking, the server sits there listening for incoming packets from any one of many simultaneously-open sockets.   (A single thread is doing this!)   When a packet arrives from any one of the sockets, the message is read, processed, and a reply is sent back on that socket.   Meanwhile, the server is also listening for new connection-requests.   If the replies can be made within a few milliseconds, nothing more than a single thread is needed.

If the tasks that can be requested are such that it takes more than a trivial amount of time to do them, the server’s architecture becomes a little more complicated, because it is now managing a pool of worker-threads.   Apache Server (or any web-server, for that matter) is a quintessential example of this.

The key point is to realize that whatever-it-is that you’re doing is not a new use-case, therefore you really don’t have to “invent” anything.   There is nothing to “build” here, and, since the available software is all free, nothing to “buy.”   Extremely sophisticated and battle-tested servers, and clients, can simply be lifted off the shelf.   To begin (in the case of Perl), surf to http://search.cpan.org and type the word server ...

Replies are listed 'Best First'.
Re^2: How to serve multiple socket clients Perl
by perlnwb (Initiate) on Mar 23, 2015 at 20:38 UTC
    I cannot figure out how to switch between clients. I mean that I need to accept all possible connections, but I need to communicate only with one client at once, so other can send information, or if it possible to notificate them that now server is not instresting in your information, so you have to wait until it call you. I have only one , but stupid idea, so I am asking here for some better approach. As for my idea, clients are sending data to server for instance each second, server accpets this data and place it in array and when server switches to another client data it will read info from array assigned to this client. But here memory synchronization comes into play, so it is bad idea. It would be great to make it possible for server to switch beetween clients , other should sleep at this time, or something other not interrupting server , or to do this in way that doesn't affect on connection betw een server and focused client. I have no building block to do this taks, so I asked this question to get some advices or directions.

      Some examples of async servers in:

      https://blog.afoolishmanifesto.com/posts/concurrency-and-async-in-perl +/

      Here's some building blocks for you. It's just an extension of the example at the end of the IO::Select perldoc page with some features from your stated problem added.

      #!/usr/bin/perl # http://perlmonks.org/?node_id=1120916 use IO::Socket; use IO::Select; use strict; my ($port, $current, $cycle) = (shift // 6667); my $listen = IO::Socket::INET->new(LocalPort => $port, Listen => 9, Re +use => 1) or die "$@ opening socket on port $port"; my $sel = IO::Select->new($listen, 0); while(1) { for my $h ($sel->can_read) { if($h == $listen) { $sel->add(my $new = $h->accept); $current //= $new; print "accepted from: ", $new->peerhost, ":", $new->peerport, "\ +n"; } elsif($h == 0) { sysread STDIN, my $in, 1024; # ignore $current = (grep $_ > 0 && $_ != $listen, $sel->handles) [++$cycle % ($sel->count - 2 || 1)]; print $current ? "switch to " . $current->peerhost . ':' . $current->peerpor +t . "\n" : "no clients\n"; } elsif(sysread $h, my $in, 1024) { $h == $current and print $in; } else { $sel->remove($h); $h == $current and undef $current, print "client exited\n"; } } }

      As others (including me) have said, this kind of problem should be done in one of the async frameworks, but sometimes a plain example can make for a decent tutorial.

      Or not.

      You don't "switch between clients". Your callback gets data from all clients, and you simply ignore data from any client except the "current client" (keep a $currentclient :).

      Have a callback from STDIN to switch which client is the "current client".

      I hope this helps.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1120990]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2024-04-20 13:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found