我已经在Perl中实现了一个小型web服务器。它正在使用IO :: Socket :: INET和IO :: Socket :: SSL并行进行侦听。Perl,IO :: Socket :: SSL,多线程
如果连接出现在HTTP端口,我启动一个线程并处理IO :: Socket :: INET引用。
由于Net :: SSLeay(IO :: Socket :: SSL中的线程限制,在文档中表示不是线程安全的,低于1.43),我没有对SSL进行并行化。我只是在相同的上下文中调用处理函数。 在HTTP的并行化情况下,处理函数是线程函数。
所有这些按预期工作时间更长。
我现在已经更新了我的系统。现在我的Net :: SSLeay是1.72,我也尝试了SSL的同步 - 就像我用HTTP做的一样。但是我在第一次阅读时遇到了分段错误。
use strict;
use warnings;
use IO::Handle;
use Fcntl ("F_GETFL", "F_SETFL", "O_NONBLOCK");
use Time::HiRes ("usleep");
use Socket;
use IO::Socket::SSL;
use threads;
STDOUT->autoflush();
my $port = "4433";
my $cer = "cer.cer";
my $key = "key.key";
my $sock = IO::Socket::SSL->new (Listen => SOMAXCONN, LocalPort => $port,
Blocking => 0, Timeout => 0, ReuseAddr => 1, SSL_server => 1,
SSL_cert_file => $cer, SSL_key_file => $key) or die [email protected];
my $WITH_THREADS = 0; # the switch!!
for (;;)
{
eval
{
my $cl = $sock->accept();
if ($cl)
{
print ("\nssl connect");
if ($WITH_THREADS == 0)
{
# this is no multi-threading
client ($cl);
}
else {
# with multithreading
my $th = threads->create (\&client, $cl);
$th->detach();
}
}
}; # eval
if ([email protected])
{
print "ex: [email protected]";
exit (1);
}
usleep (100000);
} # forever
sub client # worker
{
my $cl = shift;
# unblock
my $flags = fcntl ($cl, F_GETFL, 0) or die $!;
fcntl ($cl, F_SETFL, $flags | O_NONBLOCK) or die $!;
print "\n" . $cl->peerhost . "/" . $cl->peerport;
my $ret = "";
for (my $i = 0; $i < 100; $i ++)
{
$ret = $cl->read (my $recv, 5000);
# faults here if with threads!
if (defined ($ret) && length ($recv) > 0)
{
print "\nreceived $ret bytes";
}
else
{
print "\nno data";
}
usleep (200000);
}
print "\nend client";
$cl->close();
}
我也看过一些帖子,他们说IO ::插座:: SSL是不是线程安全的,但我不知道这仍是如此。
有谁知道这是可能的吗?或者,也许这是可能的,但我处理了错误的方式...
谢谢, 克里斯
编辑:我使用Debian 8.3用Perl 5.20.2。 Net :: SSLeay是1.72,IO :: Socket :: SSL是2.024。 OpenSSL 1.0.1k
编辑:更改代码示例为功能齐全的小样本程序。
我不熟悉的prefork的想法。你能不能简单地解释一下你如何处理你必须在一个地方监听的问题(socket监听器),然后把它推送给一个工作者。 我可以想象一个后叉(在接受之后),但在接受之前我该怎么做? – chris01
对不起,请忽略我的意见 – ikegami
只看了一下httpd,它的prefork背后有什么想法。如果它不适用于perl线程,也许我会考虑它。但我会优先考虑当前的想法。 – chris01