Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

socket lost by buffer overflow

by seal3 (Initiate)
on Dec 21, 2004 at 23:05 UTC ( [id://416652]=perlquestion: print w/replies, xml ) Need Help??

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

Hi all. Sorry for my bad english but i m french. Hope you will understand : I wrote a perl chat server using IO::Socket::INET and IO::Select. The problem is when a user lost his internet conection. The server dont know this and keep the socket opend. A "netstat -alpe | grep perl" command show me that the send-Q buffer of the lost socket is growing each time data have to be sent to the lost client. When the buffer is growing over 11000 bytes, all sockets become blocked but the server is still running. I tryed to increase the socket buffer size using the setsockopt() but it change nothing. Have you ever seen it, and found a solution ? Thanks all !

Replies are listed 'Best First'.
Re: socket lost by buffer overflow
by dug (Chaplain) on Dec 22, 2004 at 00:07 UTC
    IO::Select->can_read() returns sockets with errors as well as sockets that are readable. My guess is that somewhere in there you have a read() or a sysread() or some other function that reads from the socket without testing for an error condition during that piece of code execution.

    Here is a simple echo server that uses blocking IO and reports sockets that have errors.
    #!/usr/bin/perl use warnings; use strict; use IO::Socket; use IO::Select; use POSIX qw( BUFSIZ ); my $ALIVE = 1; $SIG{ INT } = sub { warn "killed by interupt"; $ALIVE--; }; my $sock_group = IO::Select->new(); my $server = IO::Socket::INET->new( Listen => 1, LocalPort => 8080, ) or die $@; $sock_group->add( $server ); while ( $ALIVE ) { foreach my $sock ( $sock_group->can_read() ) { if ( $sock == $server ) { $sock_group->add( $server->accept() ); } else { # first we try to read my $buf; my $rrv = sysread( $sock, $buf, BUFSIZ ); # if there is a read error unless ( $rrv ) { # we first report the error if ( $rrv == 0 ) { warn "$sock reached end of file"; } elsif ( not defined $rrv ) { warn "$sock had error: $!"; } else { warn "sock had an untrappable error"; } # and then remove the socket from our set $sock_group->remove( $sock ); $sock->close(); next; } # echo back what was said my $wrv = syswrite( $sock, $buf ); unless ( $wrv == length( $buf ) ) { if ( defined $wrv ) { warn "incomplete write on $sock"; } else { warn "write had error: $!"; } $sock_group->remove( $sock ); $sock->close(); } } } }
    Hope that helps a bit,

    -- Douglas Hunter
Re: socket lost by buffer overflow
by elwarren (Priest) on Dec 22, 2004 at 00:07 UTC
    You should check the return of the print to your socket for undef. This means the other end of the connection is gone. You don't have any code, so this is just my assumption. Change your code to do something like this:
    my $sockstatus; while (<YOURLOOP>) { $sockstatus = print $socket $data; last unless $sockstatus; }

    hth!

      Hi :-)

      Dug's method will handle when the os notifies us when the tcp keepalive mechanism determines that the client is no longer there if the client doesn't close the tcp connection itself.

      elwarren's method will proactively perform a 'ping' to the client to determine if the client is no longer there.

      Which to use? Depends if you when you need to know when a client connection disappears. Do you really need to know if it disappears within 10 seconds?

      IMHO, a connectionless (udp based) would be preferrable. There is a simple example in the Perl Cookbook IIRC.

      Jason L. Froebe

      Team Sybase member

      No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1

        The problems seal3 is seeing is on writing to a socket, not reading from it. I just posted the simplest solution.

        seal3 can you show us your code?

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (None)
    As of 2024-04-25 00:02 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found