2012-12-27 146 views
4

我在使用Perl服务器中的套接字时遇到了一些麻烦。您如何知道套接字客户端断开连接?

你怎么知道刚刚断开的(非阻塞)客户端? 在C,我已经习惯了做

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

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

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

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

+0

您是否使用任何异步框架? – creaktive

+2

注意。当你说“如果没有数据可用,recv返回-1”。这不完全正确。当没有可用数据时,recv将返回-1,并将errno设置为EAGAIN或EWOULDBLOCK。但还有其他一些情况,recv可能返回-1 - 主要是由于TCP连接中断(例如,远程对象崩溃而没有关闭socket,失去互联网等)。换句话说,你不应该依赖recv返回的“-1”。始终检查相应的errno以查看它是否是可恢复的错误。 – selbie

+0

谢谢@selbie,我不知道。 – Fabien

回答

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防止不好尝试一个断开连接的套接字,它将以套接字io错误结束您的脚本。

希望这会有所帮助!

相关问题