You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AnyEvent::Socket连接UNIX域套接字无法读取客户端消息

问题原因及修复方案

核心问题1:服务端Handle对象被GC回收

AnyEvent::Handle 依赖外部强引用维持生命周期,你在连接回调内定义的$hdl是局部变量,回调执行完成后无任何引用指向它,会被Perl垃圾回收机制自动销毁,对应连接直接被关闭,无法读取后续发送的数据。

核心问题2:客户端提前退出导致数据未发送

$hdl->push_write只是将数据写入AnyEvent的用户态发送缓冲区,并未立刻同步到socket。你写完直接调用$done->send触发进程退出,缓冲区数据还没发出去就被释放了。

修复后的代码

服务端修复版

#!/usr/bin/perl
use strict;
use warnings;
use feature 'say' ;
use AnyEvent ;
use AnyEvent::Socket ;
use AnyEvent::Handle ;

# 全局池保存Handle引用,避免被GC回收
our @ACTIVE_HDLS;

tcp_server 'unix/', '/tmp/.mysocket', sub {
    my ( $fh, @args ) = @_ ;
    say "Received request" ;
    my $hdl = AnyEvent::Handle->new( 
        fh => $fh,
        # 连接断开时清理引用
        on_eof => sub {
            my ($hdl) = @_;
            $hdl->destroy;
            @ACTIVE_HDLS = grep { $_ != $hdl } @ACTIVE_HDLS;
        },
        on_error => sub {
            my ($hdl, $fatal, $msg) = @_;
            say "Connection error: $msg";
            $hdl->destroy;
            @ACTIVE_HDLS = grep { $_ != $hdl } @ACTIVE_HDLS;
        }
    ) ; 
    # 把Handle加入全局池保持引用
    push @ACTIVE_HDLS, $hdl;

    $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" ) ;
    # 等待缓冲区所有数据写入完成后再退出
    $hdl->on_drain(sub {
        my $hdl = shift;
        $hdl->destroy;
        $done->send ;
    });
}  ;

$done->recv ;
say $! if $!;
exit ;

验证方法

  1. 先启动服务端,会打印Bound to /tmp/.mysocket
  2. 再运行客户端,会打印Connected
  3. 服务端会依次打印Received request和Received Hello world!

内容的提问来源于stack exchange,提问作者Hannibal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 15:54:02