2

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

服务器(更新):

#!/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变量我解决了这个(非)问题,但服务器仍然没有收到客户端发送的消息。

4

1 回答 1

2

我还不确定是什么导致了“非法搜索错误”,但我发现了一些至少现在可以工作的东西。客户端需要在连接回调中使用条件变量:

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;
于 2021-10-16T18:48:34.447 回答