下面的代码确实运行了一个 TCP 服务器,它在收到 TCP 请求时 fork 一个新进程。为什么它在接受第一个请求后就退出?
#!/usr/bin/perl
use Socket;
use POSIX qw(:sys_wait_h);
sub REAPER {
1 until -1 == waitpid(-1, WNOHANG);
$SIG{CHLD} = \&REAPER;
}
$SIG{CHLD} = \&REAPER;
socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1);
$my_addr = sockaddr_in(8080, INADDR_ANY);
bind SERVER, $my_addr;
listen(SERVER, 1000);
REQUEST:
while (accept(CLIENT, SERVER)) {
if ($pid = fork) {
close CLIENT;
next REQUEST;
}
die "$!" unless defined $pid;
close SERVER;
print CLIENT "hello\n";
close CLIENT;
exit;
}
最佳答案
它退出是因为 accept
被信号 (SIGCHLD) 中断,并且您不处理这种情况。尝试 perlipc: Internet TCP Clients and Servers 中更复杂的版本(向下滚动到多线程版本)。
此外,请考虑使用一个为您处理这些详细信息的模块。 Net::Server::Fork与您似乎想写的类似。如果您不喜欢某个模块,还有其他模块。
无论如何,这里对您的版本进行了一些最小的修正:
#!/usr/bin/perl
use strict;
use warnings;
use Socket;
use POSIX qw(:sys_wait_h);
sub REAPER {
local $!; # Don't let signal handler mess with $!
1 until -1 == waitpid(-1, WNOHANG);
$SIG{CHLD} = \&REAPER;
}
$SIG{CHLD} = \&REAPER;
socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1);
my $my_addr = sockaddr_in(8080, INADDR_ANY);
bind SERVER, $my_addr;
listen(SERVER, 1000);
REQUEST:
while (1) {
my $paddr = accept(CLIENT, SERVER) || do {
# try again if accept() returned because a signal was received
next REQUEST if $!{EINTR};
die "accept: $!";
};
my $pid;
if ($pid = fork) {
close CLIENT;
next REQUEST;
}
die "$!" unless defined $pid;
close SERVER;
print CLIENT "hello\n";
close CLIENT;
exit;
}
关于perl - 关于Perl TCP套接字编程的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4536229/