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

Perl6 IO::Socket::Async服务器抛出connection reset by peer异常求助

解决Perl6 IO::Socket::Async服务器的"connection reset by peer"异常

这个问题其实挺常见的,本质是客户端断开连接的方式不够优雅,导致服务器端的异步Socket在尝试读取数据时触发了TCP层面的连接重置错误。咱们一步步来分析和解决:

问题根源

看你的客户端代码,发送完{time}\n之后就直接退出了,既没有主动关闭连接,也没等数据交互完成。这时候客户端进程结束,操作系统会直接关闭Socket连接,但大概率没给服务器发送正常的FIN终止包;而服务器这边的$conn.Supply.lines还在监听输入,尝试读取时就会抛出connection reset by peer异常。

解决方案一:服务器端捕获异常,避免崩溃

咱们可以在服务器的异步监听块里加上异常捕获逻辑,把这个错误处理掉,不会影响服务器继续处理其他连接。修改后的服务器代码如下:

#!/usr/bin/env perl6
my $port = 3333 ;
say "listen port $port" ;
react {
    my $ids = 0 ;
    whenever IO::Socket::Async.listen('0.0.0.0', $port ) -> $conn {
        my $id = $ids++ ;
        $conn.print( "$id: hello\n") ;
        # 监听客户端输入,同时捕获连接重置异常
        whenever $conn.Supply.lines -> $line {
            say "$id: $line" ;
            $conn.print( "$id : $line\n") ;
        } CATCH {
            when X::IO::Socket::ConnectionReset {
                say "$id: 客户端连接已重置,异常已处理" ;
            }
        }
    }
}

这里用CATCH块专门捕获X::IO::Socket::ConnectionReset类型的异常,打印日志后就不会让服务器崩溃了。

解决方案二:客户端优雅关闭连接

从源头避免这个问题,让客户端发送完数据后主动关闭连接,给服务器发送正常的终止信号。修改客户端代码:

#!/usr/bin/env perl6
my $port = 3333 ;
my $conn = await IO::Socket::Async.connect('localhost', $port );
$conn.print: "{time}\n";
# 短暂等待确保数据发送完成(可选,根据实际场景调整时长)
await Promise.in(0.1);
# 主动关闭连接
await $conn.close;

这样客户端会正常发送FIN包,服务器端的Supply会正常结束,不会触发连接重置的异常。

补充说明

connection reset by peer是TCP协议层的错误,通常发生在:

  • 客户端进程意外崩溃,没有正常关闭Socket
  • 客户端网络突然中断
  • 防火墙主动切断了连接

所以服务器端做好异常捕获是更稳妥的方案,能应对各种异常断开的情况;客户端优雅关闭则能避免大部分场景下的错误触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:29:45