Multithreading Windows上的Perl套接字接受线程失败
我们有一个Perl系统,它打开监听器套接字,然后生成线程来实际接受和处理连接。我们在WindowsServer2008上运行,并且运行Perl5.8.8(这是一个相当旧的系统) (顺便说一句,这在Linux上运行得很好,我们在Linux上使用了fork,但在Windows上fork的实现并不是最理想的) 我们正在使用以下代码创建套接字:Multithreading Windows上的Perl套接字接受线程失败,multithreading,perl,sockets,Multithreading,Perl,Sockets,我们有一个Perl系统,它打开监听器套接字,然后生成线程来实际接受和处理连接。我们在WindowsServer2008上运行,并且运行Perl5.8.8(这是一个相当旧的系统) (顺便说一句,这在Linux上运行得很好,我们在Linux上使用了fork,但在Windows上fork的实现并不是最理想的) 我们正在使用以下代码创建套接字: use Socket; ...; unless ( ($rSock) = IO::Socket::INET->new( Loc
use Socket;
...;
unless (
($rSock) = IO::Socket::INET->new(
LocalPort => $aChannelConfig{$sChannel}->{nPort},
Proto => 'tcp',
Type => SOCK_STREAM,
Reuse => 1,
Listen => $aChannelConfig{$sChannel}->{nListen},
)
and $rSock
)
{
$sErrNote = "Cannot create tcp listener socket: sChannel=$sChannel sService=>$aChannelConfig{$sChannel}->{nPort} Err=$!";
}
当派生的进程接受套接字时,只有第一个进程可以正常工作
问题在于后续进程只是从IO::Socket::accept获取undef-在下面的核心IO::Socket::accept代码中,调用\u accept\u返回undef(我们没有使用超时)
我们可能需要使用套接字选项来允许不同的线程接受它
谁能给我一些指点吗
编辑
我们创建线程的调用是:
my $thr = server::start_thread(\&_start_server_process,$sServerType,$sIcPipe,$rIcSock,'thread');
sub start_thread {
my $thr = threads->create(@_) or return;
return $thr;
}
编辑2
成功和不成功调用的日志输出如下:
Successful accept:
2014-09-22 08:55:32,575 p:2532.5 e:2532.5 s:OA.2 DEBUG : CADETserver::channel_accept - !!! - TCP socket accept. Channel=oa rH=IO::Socket::INET=GLOB(0x743c4ac)
2014-09-22 08:55:32,635 p:2532.5 e:2532.5 s:OA.2 DEBUG : CADETserver::channel_accept - !!! - TCP socket accept result. Channel=oa $@= $rClient=IO::Socket::INET=GLOB(0x9fb2d3c)
Unsuccessful accept:
2014-09-22 08:55:32,575 p:2532.6 e:2532.6 s:OA.3 DEBUG : CADETserver::channel_accept - !!! - TCP socket accept. Channel=oa rH=IO::Socket::INET=GLOB(0x7aef7d4)
2014-09-22 08:55:32,606 p:2532.6 e:2532.6 s:OA.3 DEBUG : CADETserver::channel_accept - !!! - TCP socket accept result. Channel=oa $@= $rClient=
请注意,我们只是得到一个未定义的客户端套接字,并且没有在中记录任何错误$@
生成上述日志输出的代码如下所示——正如您所看到的,我们只是调用accept,没有任何参数
my $rH = $rHndlHandles{$sCurrServerType}{$rSock};
$l4p->debug("!!! - TCP socket accept. Channel=$sChannel rH=$rH");
my $rClient;
eval {
local $SIG{__DIE__} = 'IGNORE';
$rClient = $rH->accept();
};
$l4p->debug('!!! - TCP socket accept result. Channel=' . $sChannel . ' $@=' .$@ . ' $rClient=' . $rClient );
有趣的是我正在研究问题是否在于如何将套接字设置为非阻塞。我们目前的代码如下:
ioctl ($rSock, 0x8004667E, \$temp); # set non-blocking
当我将其更改为:
use constant FIONREAD => 0x4004667f;
my $numbytes = "\x00" x 4; # pack('L',0) works too
ioctl($rSock, FIONREAD, unpack('I',pack('P',$numbytes)));
my $nbytes = unpack('I',$numbytes);
(感谢贝尔蒙克斯上的比特希夫特-)
这允许套接字接受OK,但套接字无法可靠通信
所以。。。这与我们如何将套接字设置为非阻塞有关吗?是否使用线程作为选项,而不是使用叉?我相信Perl线程在Windows上工作得更好。您能否显示创建线程的代码,或者至少显示您在accept成功和失败时添加的调试打印行的输出?@sobrique-我们使用的是线程,而不是分叉。@atcynth-我添加了线程调用。将在适当的时候添加成功接受的输出。谢谢。您是为每个服务器套接字启动一个线程,还是创建一个服务器套接字并将其传递给多个线程?
use constant FIONREAD => 0x4004667f;
my $numbytes = "\x00" x 4; # pack('L',0) works too
ioctl($rSock, FIONREAD, unpack('I',pack('P',$numbytes)));
my $nbytes = unpack('I',$numbytes);