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
相关产品推荐
相关产品推荐

