如何在Perl中测试TCP套接字状态?

时间:2010-03-24 11:53:11

标签: perl sockets tcp

我有一个读取数据的TCP套接字。当读取数据时发生错误,我返回一个undef(NULL)值。错误格式化的消息或损坏的套接字可能导致错误。有人能告诉我是否有一个返回套接字状态的特定函数?

2 个答案:

答案 0 :(得分:6)

有三种方法可以检测插座是打开还是关闭,但它们都不是100%完全校样。

第一个是to attempt a read on the socket as follows

my $ret = recv($sockfd, $buff, 1, MSG_PEEK | MSG_NOWAIT);

如果套接字已经过有序关闭,即名为shutdown for writing or called close AND 的对等方已到达FIN数据包,则此调用将导致0长度读取指示一个封闭的插座。如果您的对等应用程序崩溃,这也会有所帮助,因为操作系统将关闭连接并发送FIN。但是,如果您的对等机器已崩溃或您的对等应用程序已锁定,则无法帮助您,因为连接的每一端都保持独立状态。

检测断开连接的第二种方法是探测你的同伴。如果您向对等方发送0长度数据包(应该能够处理)并且应用程序已崩溃,那么您发送第二个0长度数据包,您的应用程序将获得SIG_PIPE信号indicating a broken pipe

处理此问题的另一种方法是使用应用程序级心跳,其中对等方定期向对方发送心跳包,表明它们处于活动状态且运行正常。

最后一个选项是使用SO_KEEPALIVE套接字选项,虽然这个用途有限,因为它只会在大约2小时不活动后检测到损坏的套接字。

如果您在连接断开时必须非常快速地知道,那么最可靠的选项可能是应用程序级别的心跳。

答案 1 :(得分:5)

doh!,回想起来答案显而易见,使用连接电话。

$socket = IO::Socket::INET(localhost, 1000);
die "no connection" unless $socket -> connected();
$socket -> send("your face here for $20");
die "socket is dead" unless $socket -> connected();
$socket -> recv($data);