Perl 代码使用 IO::SELECT 和 IO::Socket::UNIX 正常退出,但使用 NETCAT (nc) 不退出,为什么?
Perl code is exiting without an error using IO::SELECT and IO::Socket::UNIX but doesn't exit using NETCAT (nc) why?
看起来(对我来说)PERL 没有错误就崩溃了,但(对我来说)我一定是做错了什么。一切看起来都非常奇怪,因为 PERL exits 中间代码没有错误,它不应该......除非我错了......这可能是我......这就是为什么我正在寻求帮助!
我已经确认下面的代码与原始 CENTOS 8(我使用的是 Rocky)系统表现出相同的行为并且它 EXITS...请有人帮助我并解释为什么我真的不知道发生了什么,所以我正在寻求帮助!
两个简单的 PERL 程序:
./listen_socket.pl
./send_socket.pl sending_this
发送套接字实际上是一个简单的 netcat...nc。
NETCAT 有效....如果我使用:
echo send_this | nc -U /tmp/whydontyouwork.sock
then "listen_socket.pl" 不会退出并按预期运行。
如果我执行这个:
./send_socket.pl send_this
然后就失败了。
我不明白为什么。
请帮助我并告诉我我在哪里是个白痴因为我不知道!
这是两个 perl 程序:(listen_socket.pl) 和 (send_socket.pl)
listen_socket.pl:
use warnings;
use IO::Select;
use IO::Socket::UNIX;
my $SOCK_PATH = "/tmp/whydontyouwork.sock";
my $socket;
my $sel = IO::Select->new();
unlink $SOCK_PATH;
setup();
main();
print STDERR "I know I never get here...see below..\n";
sub setup {
$socket = new IO::Socket::UNIX(
Type => SOCK_STREAM,
Local => $SOCK_PATH,
Listen => 5,
);
$sel->add($socket);
}
sub main {
while ( 1 == 1 ) {
while(my @ready = $sel->can_read(1)) {
foreach my $fh (@ready) {
if($fh == $socket) {
# Create a new socket
my $new = $socket->accept;
$sel->add($new);
}
else {
# Process socket
if ( 1 == 1 ) {
my $data = <$fh>;
if ( defined $data ) {
print STDERR "I am here...I GET HERE!!";
print $fh "\n";
print STDERR "..and all done and I NEVER GET HERE!!??.\n";
$sel->remove($fh);
$fh->close;
}
}
print STDERR "Howdie here? Nope..\n";
}
}
}
}
}
send_socket.pl:
#!/usr/bin/perl
use Socket;
my $SOCK_PATH = "/tmp/whydontyouwork.sock";
if ( $ARGV[0] ) {
socket(CLIENT, PF_UNIX, SOCK_STREAM, 0);
connect(CLIENT, sockaddr_un($SOCK_PATH));
print CLIENT $ARGV[0] ;
close CLIENT;
exit;
}
exit 1;
作品==>
echo send_this | nc -U /tmp/whydontyouwork.sock
不工作 ==>
perl ./send_socket.pl send_this
您应该添加每个 运行 的输出,至少告诉我们听众死于 Broken pipe
这会让您的问题更加明显。
无论如何,看起来您的发送方正在关闭套接字,然后侦听器正在尝试写入它。
从技术上讲,您可以忽略破损的管道,并通过将 $SIG{PIPE} = 'IGNORE';
添加到侦听器来使 perl 示例的输出相同,但这当然不能解决(缺少)逻辑问题。
但是,实际上,您应该阅读更多有关使用套接字编程的内容,因为您尝试做的事情没有多大意义,而且,更重要的是,您实际上应该注意错误消息提示正在发生的事情。
看起来(对我来说)PERL 没有错误就崩溃了,但(对我来说)我一定是做错了什么。一切看起来都非常奇怪,因为 PERL exits 中间代码没有错误,它不应该......除非我错了......这可能是我......这就是为什么我正在寻求帮助!
我已经确认下面的代码与原始 CENTOS 8(我使用的是 Rocky)系统表现出相同的行为并且它 EXITS...请有人帮助我并解释为什么我真的不知道发生了什么,所以我正在寻求帮助!
两个简单的 PERL 程序:
./listen_socket.pl
./send_socket.pl sending_this
发送套接字实际上是一个简单的 netcat...nc。
NETCAT 有效....如果我使用:
echo send_this | nc -U /tmp/whydontyouwork.sock
then "listen_socket.pl" 不会退出并按预期运行。 如果我执行这个:
./send_socket.pl send_this
然后就失败了。
我不明白为什么。 请帮助我并告诉我我在哪里是个白痴因为我不知道!
这是两个 perl 程序:(listen_socket.pl) 和 (send_socket.pl)
listen_socket.pl:
use warnings;
use IO::Select;
use IO::Socket::UNIX;
my $SOCK_PATH = "/tmp/whydontyouwork.sock";
my $socket;
my $sel = IO::Select->new();
unlink $SOCK_PATH;
setup();
main();
print STDERR "I know I never get here...see below..\n";
sub setup {
$socket = new IO::Socket::UNIX(
Type => SOCK_STREAM,
Local => $SOCK_PATH,
Listen => 5,
);
$sel->add($socket);
}
sub main {
while ( 1 == 1 ) {
while(my @ready = $sel->can_read(1)) {
foreach my $fh (@ready) {
if($fh == $socket) {
# Create a new socket
my $new = $socket->accept;
$sel->add($new);
}
else {
# Process socket
if ( 1 == 1 ) {
my $data = <$fh>;
if ( defined $data ) {
print STDERR "I am here...I GET HERE!!";
print $fh "\n";
print STDERR "..and all done and I NEVER GET HERE!!??.\n";
$sel->remove($fh);
$fh->close;
}
}
print STDERR "Howdie here? Nope..\n";
}
}
}
}
}
send_socket.pl:
#!/usr/bin/perl
use Socket;
my $SOCK_PATH = "/tmp/whydontyouwork.sock";
if ( $ARGV[0] ) {
socket(CLIENT, PF_UNIX, SOCK_STREAM, 0);
connect(CLIENT, sockaddr_un($SOCK_PATH));
print CLIENT $ARGV[0] ;
close CLIENT;
exit;
}
exit 1;
作品==>
echo send_this | nc -U /tmp/whydontyouwork.sock
不工作 ==>
perl ./send_socket.pl send_this
您应该添加每个 运行 的输出,至少告诉我们听众死于 Broken pipe
这会让您的问题更加明显。
无论如何,看起来您的发送方正在关闭套接字,然后侦听器正在尝试写入它。
从技术上讲,您可以忽略破损的管道,并通过将 $SIG{PIPE} = 'IGNORE';
添加到侦听器来使 perl 示例的输出相同,但这当然不能解决(缺少)逻辑问题。
但是,实际上,您应该阅读更多有关使用套接字编程的内容,因为您尝试做的事情没有多大意义,而且,更重要的是,您实际上应该注意错误消息提示正在发生的事情。