Perl 代码使用 IO::SELECT 和 IO::Socket::UNIX 退出时没有错误,但使用 NETCAT (nc) 时不退出,为什么?
(对我来说) PERL 似乎在没有错误的情况下崩溃了,但 (对我来说) 看起来我一定做错了什么。一切看起来都很奇怪,因为 PERL 退出 代码中没有错误,它不应该......除非我错了......这可能是我......这就是我问的原因寻求帮助!
我已经确认下面的代码与原始的 CENTOS 8(我使用 Rocky)系统表现出相同的行为,并且它EXITS...请有人帮助我并解释为什么,因为我真的不知道发生了什么事,所以我寻求帮助!
两个简单的 PERL 程序:
./listen_socket.pl
./send_socket.pl sending_this
发送套接字实际上是一个简单的 netcat...nc。
NETCAT 工作......如果我使用:
echo send_this | nc -U /tmp/whydontyouwork.sock
那么“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
It looks like (to me) PERL is crashing without an ERROR but it also looks like (to me) that I must be doing something wrong. What everything looks like is very strange as PERL exits mid-code without an ERROR and it should not... unless I am wrong... which probably I am... which is why I am asking for HELP!
I've confirmed the code below exhibits the same behavior with a virgin CENTOS 8 (I used Rocky) system and it EXITS... please can someone help me and explain why as really I don't know what things are going on so I am aksing for help!
Two simple PERL programs:
./listen_socket.pl
./send_socket.pl sending_this
Send socket is effectively a simple netcat... nc.
NETCAT works.... if I use:
echo send_this | nc -U /tmp/whydontyouwork.sock
then "listen_socket.pl" does not exit and behaves as expected.
If I execute this:
./send_socket.pl send_this
then it fails.
I don't understand why.
Please help me and tell me where I am an idiot cos I dunno!
Here are the two perl programs: (listen_socket.pl) and (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;
WORKS ==>echo send_this | nc -U /tmp/whydontyouwork.sock
NOT WORKS ==>perl ./send_socket.pl send_this
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该添加每次运行的输出,至少告诉我们监听器因
Broken pipeline
而终止,这会让您的问题更加明显。无论如何,看起来您的发送者正在关闭套接字,然后侦听器正在尝试写入它。
从技术上讲,您可以通过向侦听器添加
$SIG{PIPE} = 'IGNORE';
来忽略损坏的管道,并使输出与 perl 示例相同,但这当然不能修复 (缺乏)逻辑。但是,实际上,您应该更多地阅读有关使用套接字进行编程的内容,因为您尝试做的事情没有多大意义,而且更重要的是,您实际上应该注意错误消息以获取有关正在发生的情况的提示在。
You should have added the output of each run, at least tell us the listener dies with
Broken pipe
which would have made it more obvious what your issue is.In any case, it looks like your sender is closing the socket and then the listener is trying to write to it.
You can technically ignore the broken pipe and have your output be the same for the perl example by adding
$SIG{PIPE} = 'IGNORE';
to the listener, but that of course does not fix the (lack of) logic.But, really, you should read up a bit more about programming with sockets, as what you were trying to do did not make much sense, and, even more importantly, you should actually pay attention to the error messages for hints to what is going on.