perl - 关于Perl TCP套接字编程的问题

标签 perl

下面的代码确实运行了一个 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/

相关文章:

perl - 这可以在没有 tmp 变量的情况下写成 1 行或 2 行吗?

perl - 哈希的自定义排序方法,它将自动使用适当的哈希

带有奇怪 @INC 路径的 Mac OS 10.10 Yosemite 上的 Perl

regex - Perl 同时替换多个字符串

perl - 如何在 Windows 上使用 Perl 在命令行上处理通配符?

json - 在 Perl 中加速 JSON 解析

动态生成的 Perl Moose 访问器

perl - 如何整理 DBIx::Class::Schema::Loader 的输出?

perl - Perl OO用于创建和发送电子邮件的良好界面是什么?

perl - 你什么时候需要在 Perl 中设置 `END { close STDOUT}`?