2011-10-05 52 views
2

時使用以下,但也使用類似的代碼時IO ::插座:: INET,我有接受新的連接,一旦客戶端已斷開連接的問題。Perl的分叉插座服務器,停止接受連接,當客戶端斷開

看來父停止分叉新的孩子,直到所有先前的孩子已經結束/斷開。雖然連接被接受。

有沒有人有一個想法是什麼,我做錯了。

#!/usr/bin/perl -w 
use Socket; 
use POSIX qw(:sys_wait_h); 

sub REAPER { 
    1 until (-1 == waitpid(-1, WNOHANG)); 
    $SIG{CHLD} = \&REAPER; 
} 

$SIG{CHLD} = \&REAPER; 

$server_port=1977; 

socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')); 
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1); 
$my_addr = sockaddr_in($server_port, INADDR_ANY); 
bind(SERVER, $my_addr) 
    or die "Couldn't bind to port $server_port : $!\n"; 
listen(SERVER, SOMAXCONN) 
    or die "Couldn't listen on port $server_port : $!\n"; 
print("[$$] STARTED\n"); 
while (accept(CLIENT, SERVER)) 
{ 
    next if $pid = fork; 
     die "fork: $!" unless defined $pid; 
    close(SERVER); 
    print("[$$] CONNECTED\n"); 
    while(<CLIENT>) 
    { 
     print("[$$] $_\n"); 
    } 
    print("[$$] EXIT\n"); 
    exit; 
} 
continue 
{ 
    close(CLIENT); 
} 
print("[$$] ENDED\n"); 

回答

3

在POSIX.1-2001標準的系統,簡單地設置$SIG{CHLD} = 'IGNORE'應該solve the problem

+0

這似乎是用最少的代碼做的伎倆!謝謝。 –

1

我覺得你的問題是在REAPER - 它會循環,直到所有的孩子都已經退出,因爲你等到waitpid回報-1

你可能就要:

my $kid; 
do { 
    $kid = waitpid(-1, WNOHANG); 
} while $kid > 0; 

參見: http://perldoc.perl.org/functions/waitpid.html

+0

'waitpid'用'WNOHANG'返回0,如果子進程仍然活躍,但他們都不是準備收割。 – mob

1

的問題是,accept正在由SIGCHLD中斷。修復:

for (;;) { 
    if (!accept(CLIENT, SERVER)) { 
     next if $!{EINTR}; 
     die $!; 
    } 

    ...fork and stuff... 
} 
0

OK,我知道這是事實後三個月,但我一直有同樣的問題,試圖找到一個例子1.允許多個併發連接,它的持久性 - 它不會消失,甚至畢竟客戶已經退出。

我只是改變了REAPER功能和現代化這一點。

這裏的整個事情:

#!/usr/bin/perl -w 
use Socket; 
use POSIX qw(:sys_wait_h); 

sub reaper { 
    1 until (-1 == waitpid(-1, WNOHANG)); 
    return($SIG{CHLD}); 
} 

$SIG{CHLD} = reaper(); 

$server_port=1977; 

socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')); 
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1); 
$my_addr = sockaddr_in($server_port, INADDR_ANY); 
bind(SERVER, $my_addr) 
    or die "Couldn't bind to port $server_port : $!\n"; 
listen(SERVER, SOMAXCONN) 
    or die "Couldn't listen on port $server_port : $!\n"; 
print("[$$] STARTED\n"); 
while (accept(CLIENT, SERVER)) 
{ 
    next if $pid = fork; 
     die "fork: $!" unless defined $pid; 
    close(SERVER); 
    print("[$$] CONNECTED\n"); 
    while(<CLIENT>) 
    { 
     print("[$$] $_\n"); 
    } 
    print("[$$] EXIT\n"); 
    exit; 
} 
continue 
{ 
    close(CLIENT); 
} 
print("[$$] ENDED\n"); 
相關問題