我已經在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