Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于Perl TCP套接字编程的问题_Perl - Fatal编程技术网

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

关于Perl TCP套接字编程的问题,perl,Perl,下面的代码确实运行了一个TCP服务器,当接收到TCP请求时,它会派生一个新进程。为什么它会在第一个请求被接受之后退出 #!/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_ST

下面的代码确实运行了一个TCP服务器,当接收到TCP请求时,它会派生一个新进程。为什么它会在第一个请求被接受之后退出


#!/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)中断,而您不处理这种情况。在中尝试更复杂的版本(向下滚动到多线程版本)

也可以考虑使用一个处理这些细节的模块。类似于你想写的东西。如果您不喜欢,还有其他模块

无论如何,以下是对您的版本的一些最小更正:

#!/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;
}

我把你的问题看作是问代码是如何工作的,而不是问为什么不工作


if($pid=fork)分叉,即创建一个子进程来处理请求。在父级中,fork()返回子级的pid,因此父级关闭客户机句柄并继续等待下一个请求。只有在fork()返回0的子级中,才会执行if块之外的代码,子级处理请求,然后退出,因为父级将处理等待和处理下一个请求。

我不知道答案,但我要做的第一件事是在strace下运行它,查看系统调用的内容。如果您尝试按发布的方式运行程序,并使用netcat或其他方式连接到它,您将看到服务器在处理第一个连接后退出(原因见我的答案)。