【问题标题】:How do you know a socket client disconnected?你怎么知道一个套接字客户端断开连接?
【发布时间】:2012-12-28 10:01:25
【问题描述】:

我在 Perl 服务器中使用套接字时遇到了一点麻烦。

你怎么知道一个(非阻塞的)客户端刚刚断开连接? 在C中,我习惯做

if (recv(sock, buff, size, flags) == 0) {
    printf("Client disconnected\n";
}

或python或其他语言中的等价物:recv 如果没有可用数据,则返回 -1,如果客户端退出,则返回 0,如果可以读取数据,则返回正数。

但是 perl 的 recv 不是这样工作的,使用 $data = <$sock> 似乎没有任何可能知道。

有没有(简单的)可能性?

【问题讨论】:

  • 你在使用任何异步框架吗?
  • 注意。当您说“如果没有可用数据,recv 返回 -1”。这并不完全正确。当没有可用数据时,recv 将返回 -1,并将 errno 设置为 EAGAIN 或 EWOULDBLOCK。但在其他情况下,recv 也可能返回 -1 - 主要是由于 TCP 连接被中断(例如,远程对等方在未关闭其套接字的情况下崩溃、失去互联网等)。换句话说,你不应该依赖recv返回的“-1”。始终检查相应的 errno 以查看它是否是可恢复的错误。
  • 谢谢@selbie,我不知道。

标签: perl sockets


【解决方案1】:

你得看看perldoc perlioperldoc IO::Socket

#!/usr/bin/perl -w
use IO::Socket;

有很多方法可以使用非阻塞 IO 组合,从 PIPE 信号到 recv 您可以使用(取决于您在做什么):

return "Socket is closed" unless $sock->connected;

这就是我控制许多套接字以使用select 为它们服务的方式。当一个套接字关闭时,我必须将它们从列表中删除(没有别的,好像断开连接,套接字不再存在,所以没有必要关闭它们):

unless (eval {$group{$grp}->{'socket'}->connected}) {
    delete $group{$grp}->{'socket'};
    return 0;
};

eval 可防止对断开连接的套接字进行错误尝试,这会以 socket io 错误结束您的脚本。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多