开发者

How can I test TCP socket status in Perl?

I've 开发者_开发问答got a TCP socket which reads data. When an error occurs when reading the data, I return an undef (NULL) value. Errors can be caused by badly formatted messages or broken sockets. Can someone tell me if there is a specific function which returns the status of a socket?


There are three ways to detect whether the socket is open or closed, but neither of them are 100% full proof.

The first is to attempt a read on the socket as follows:

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

If the socket has went through an orderly shutdown, i.e. the peer called shutdown for writing or called close AND the FIN packet has arrived then this call will result in a 0 length read indicating a closed socket. This also helps if your peer application crashed since the OS will close the connection and send a FIN. However, if your peer machine has crashed or your peer application has locked up this won't help you since each end of the connection maintains independent state.

A second way to detect a broken connection is by probing your peer. If you send a 0 length packet to your peer ( which is should be able to handle ) and the application has crashed then you send a second 0 length packet your application will get the SIG_PIPE signal indicating a broken pipe.

Another way to deal with this issue is to use an application level heartbeat in which the peers periodically send a heartbeat packet to each other indicating that they are alive and functioning properly.

One last option is to use the SO_KEEPALIVE socket option, although this is of limited use since it will only detect a broken socket after approximately 2 hours of inactivity.

If you really must know fairly quickly when a connection is broken, then the most reliable option is probably going to be the application level heartbeat.


doh!, the answer was obvious in retrospect, use the connected call.

$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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜