Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Knowing when a socket connection is dead

by Forsaken (Friar)
on Jul 29, 2005 at 09:03 UTC ( [id://479302]=perlquestion: print w/replies, xml ) Need Help??

Forsaken has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,

problem is as follows: I use a combination of Socket and IO::Select, quite classic really. I open a number of socket connections using this little snippet:

sub makecon { my($self, $server, $port) = @_; my($iaddr, $paddr, $filehandle); my $proto = getprotobyname('tcp'); unless($iaddr = inet_aton($server)) { carp "No host found: $server"; + return; } $paddr = sockaddr_in($port, $iaddr); unless(socket($filehandle, PF_INET, SOCK_STREAM, $proto)) { carp "so +cket failure: $!"; return; } unless(connect($filehandle, $paddr)) { carp "connect failure: $!"; r +eturn; } return $filehandle; }
and then stuff the filehandle into IO::Select so I can perform the classic select loop to check which filehandles have data available. However, what I'm trying to do now is to implement a detection system for when a socket has died. Having read the documentation for IO::Select my first impression was that IO::Select->has_exception() would be the perfect tool to do so but for some reason it refuses to give me back anything, even though I am absolutely sure that the connection is dead on the other side. Any suggestions or ideas?


Remember rule one...

Replies are listed 'Best First'.
Re: Knowing when a socket connection is dead
by castaway (Parson) on Jul 29, 2005 at 10:34 UTC
    It's dead (disconnected), when can_read() indicates data available, but reading from it gives you no bytes. (See im2 code). I forget where I picked that up from, but it's worked for me. Why are you not using IO::Socket, btw?

    C.

      If you want to be completely sure, you need to do a little more checking. At the least, you should check if $! is EINTR. In that case, you got no data because the system call was interrupted.
Re: Knowing when a socket connection is dead
by metalgear119 (Acolyte) on Jul 29, 2005 at 12:29 UTC
    I had the same problem just recently. This is how I resolved it.
    sub socketListen { my $client = shift; # specific client connection execut +ed in this thread my $server = shift; my $server_port = shift; # port number of currently connected s +ocket # data is ready to be received over the socket # $client->autoflush(); print "connected to port: $server_port\n" if ( $debug == 1 ); my @recData = (); my $numTries = 0; # set connection up for non-blocking read # my $true=1; my $rec; ioctl($client, 0x8004667e, \$true) or return -1; while ( $quitThread == 0 ) { # try to read data # $rec = undef; my $res = sysread($client, $rec, $bufferSize); if ( defined($res) ) { if ( $res == 0 ) { # socket was closed remotely # print "received nothing on socket $server_port.\n" if +( $debug == 1 ); last; } elsif ( $res > 0 ) { # received message # print "received on socket $server_port:$rec\n" if ( $d +ebug == 1 ); } } else { # no new information came through # print "sleeping: received nothing on socket $server_port.\ +n" if ( $debug == 1 ); sleep 2; next; } } $client->close; print "closing socket $server_port...\n" if ( $debug == 1 ); }
    This was the body of a sub routine I called whenever my selector could do a "can_read" on the connection. You may want to use the "numTries" to have the connection timeout if nothing comes through over a certain time period.
Re: Knowing when a socket connection is dead
by kscaldef (Pilgrim) on Jul 29, 2005 at 16:11 UTC
    You're misunderstanding what has_exception() does. It's a little used feature of sockets where "urgent" information can be sent out-of-band. You can think of it a little like how unix processes have both STDOUT and STDERR; there's this extra channel that you can use in exceptional situations.

    That said, I've never used that feature myself and I'm not sure it's really that useful.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://479302]
Approved by Tanalis
Front-paged by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (3)
As of 2024-03-29 14:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found