Multithreading Windows上的Perl套接字接受线程失败

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

我们有一个Perl系统,它打开监听器套接字,然后生成线程来实际接受和处理连接。我们在WindowsServer2008上运行,并且运行Perl5.8.8(这是一个相当旧的系统)

(顺便说一句,这在Linux上运行得很好,我们在Linux上使用了fork,但在Windows上fork的实现并不是最理想的)

我们正在使用以下代码创建套接字:

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);