无法使用 AnyEvent::Socket 和 tcp_connect读取客户端的消息(到 UNIX 域套接字)



运行以下服务器和客户端脚本:

服务器(更新):

#!/usr/bin/perl
use strict;
use warnings;
use feature 'say' ;
use AnyEvent ;
use AnyEvent::Socket ;
use AnyEvent::Handle ;
tcp_server 'unix/', '/tmp/.mysocket', sub {
my ( $fh, @args ) = @_ ;
say "Received request" ;
my $hdl = AnyEvent::Handle->new( fh => $fh ) ; 
$hdl->push_read(
line =>  sub {
my ( $hdl, $line ) = @_ ;
say "Received $line" ;
}
) ;
}, sub {
my ( $fh, @sock ) = @_ ;
say "Bound to @sock" ;
} ;
AnyEvent->condvar->recv ;
exit ;  

客户机(更新):

#!/usr/bin/perl
use strict;
use warnings;
use feature 'say' ;
use AnyEvent ;
use AnyEvent::Socket ;
use AnyEvent::Handle ;
my $done = AnyEvent->condvar ;
tcp_connect "unix/", "/tmp/.mysocket", sub {
my ( $fh ) = @_ or die "unable to connect: $!" ;
say "Connected" ;
my $hdl = AnyEvent::Handle->new( fh => $fh ) ;
$hdl->push_write( "Hello world!n" ) ;
$done->send ;
}  ;
$done->recv ;
say $! ;
exit ;

服务器接收并接受连接请求,但客户端收到一个"非法搜索";错误,跳过在tcp_connect中定义的回调,并且不发送"Hello world"给服务器的消息。

我做错了什么?

更新好吧. .我发现,由于AnyEvent模块的异步性质,客户端得到了"非法搜索"。因为剧本结束了。添加一个condvar变量我解决了(非)问题,但服务器仍然没有收到客户端发送的消息。

我不确定是什么原因导致"非法查找错误";还没有,但我找到了一个至少目前有效的方法。客户端需要在连接回调中使用条件变量:

my $client_done = AnyEvent->condvar;
tcp_connect "unix/", "/tmp/.mysocket", sub {
my ( $fh ) = @_ or die "unable to connect: $!" ;
say "Connected" ;
my $hdl = AnyEvent::Handle->new( fh => $fh ) ;
$hdl->push_write( "Hello world!n" ) ;
$client_done->send;
};
$client_done->recv;
say "Done";

另外,服务器不应该使用on_read回调,而应该使用push_read()方法:

my $server_done = AnyEvent->condvar;
tcp_server 'unix/', '/tmp/.mysocket', sub {
my ( $fh, @args ) = @_ ;
say "Received request" ;
my $hdl ;
$hdl = AnyEvent::Handle->new(
fh      => $fh,
on_eof   => sub {
say "server_eof";
$server_done->send;
undef $hdl;
}
);
$hdl->push_read (
line => sub {
say "server got line <$_[1]>";
}
);
}, sub {
my ( $fh, @sock ) = @_ ;
say "Bound to @sock" ;
};
say "Waiting for server done..";
$server_done->recv;

最新更新