Multithreaded server in Perl? Easy!

Interesting? Welcome to cat.
Preparation, or what we need
First of all, of course, Perl itself is needed. Any more or less modern version will do. I’ll say right away how to do this under Windows, I don’t know, I didn’t check the code, but it should work.
As it turned out, CPAN already has a ready-made Net :: Server module for such tasks . Download and install it using the tools of your package manager (libnet-server-perl in Debian / Ubuntu) or directly cpan (for an amateur):
cpan Net::ServerTheory
Net :: Server provides several models for working with multi-threading: Single (one thread), Fork (a new child process for each connection), PreFork (similar, but smarter), INET (for use with inetd), MultiType (choosing one of the models - from the configuration or automatically) and so on. I personally like PreFork (quite simple and stable, but effective), and I will use it. In reality, it is better to use MultiType - it can fallback to another model if the one we need is not available.
Everything that this package provides (module, class, as you want) is the base. You need to inherit it, redefine several functions (okay, okay, at least one!), Give it a config, and then run it. In fact, all we need is a base class. You need to add just a little bit. The basic version described in synopsis (which, however, is not without some Perl magic - for example, inheritance without declaring an inheritor class), looks like this:
#!/usr/bin/perl
use Net::Server::PreFork;
@ISA = qw(Net::Server::PreFork);
sub process_request {
#...code...
}
__PACKAGE__->run();Works. Simply. Strong. Effectively. And nifiga is not clear (which, in general, is also a plus - you can show it to someone). In practice, we will bring it all into a more human form.
Practice
For a program, it is better to select a folder somewhere. We will have 3 files (package, configuration and the executable itself). Without further ado, the code:
lib / Net / Server / Hello.pm
#!/usr/bin/perl
package Net::Server::Hello; # Объявляем свой пакет
use strict; # Так в книжке написано ;)
use warnings;
use base qw(Net::Server::PreFork); # Наследуем
sub process_request { # Собственно, здесь и выполняется вся работа с запросом
my $self = shift; # Получаем ссылку на себя. Это Perl ООП-магия
while () { # Net::Server дает нам сокет как STDIN + STDOUT!
print "Hello!\n"; # Отвечаем. Просто отвечаем на любой запрос клиента.
}
}
1; # Perl-магия: пакет должен иметь return etc / myserver.cfg
# Формат - ключ значение
port 9999
proto tcpbin / myserver.pl
#!/usr/bin/perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib"; # Хороший тон: держим исполняемый файл в bin,
# а библиотеки (пакеты) - в lib, и т.д.
use Net::Server::Hello;
# Создаем экземпляр своего сервера; параметры, кстати, можно задавать в командной строке
our $server = Net::Server::Hello->new(conf_file => "$FindBin::Bin/../etc/myserver.cfg");
$server->run(); # Поехали!If you now start it all, connect to it with telnet and ask something, you get something like the following:
$ telnet 127.0.0.1 9999
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Привет!
Hello!
Hi!
Hello!
Терморектальный криптоанализ
Hello!
^]quit
telnet> quit
Connection closed.
What's next?
Using the Net :: Server is not limited to writing unpretentious network «Hello world»
Picture from xkcd .
If anything, this is my first habratopik, so please rotten eggs to throw right at me at habrahpost.