http://qs1969.pair.com?node_id=771242

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

I was writing a simple pair of scripts to test out IO::Socket; reader.pl which opens the port, listens and prints out whatever it's fed and writer.pl which writes to the socket. For fun I turned writer.pl into an infinite loop, however after a while it fails to connect.
reader.pl
#!/usr/bin/perl use strict; use warnings; use IO::Socket; my $socket = new IO::Socket::INET( LocalHost => '127.0.0.1', LocalPort => 7070, Proto => 'tcp', Listen => 1, Reuse => 1, ); die "Could not create socket\n" unless $socket; while( 1 ) { my $input = $socket->accept(); print <$input> ."\n"; close( $input ); }
writer.pl
#!/usr/bin/perl use strict; use warnings; use IO::Socket; sub makeSock { my $socket = new IO::Socket::INET( PeerAddr => 'localhost', PeerPort => 7070, Proto => 'tcp', ); die "Could not connect\n" unless $socket; return $socket; } my $i = 1; while( 1 ) { my $socket = makeSock(); print $socket $i; close( $socket ); $i++; }
Removing the print statement in reader.pl fixes this, but replacing print with sleep(1) doesn't make it occur (I thought the slight delay in making it print must have been blocking).

When it happens, writer.pl can eventually be restarted (it instantly dies with "Could not connect" a few times though) while leaving reader.pl running. That suggests that reader.pl stops responding but even after killing reader.pl and restarting both scripts, writer.pl instantly dies a couple of times.

Why is this happening?

Replies are listed 'Best First'.
Re: IO::Socket disconnects in loop
by ikegami (Patriarch) on Jun 13, 2009 at 19:48 UTC

    writer.pl can eventually be restarted (it instantly dies with "Could not connect" a few times though)

    That makes no sense. Or is does "it" in the parens refer to the reader? How can it die more than once? How it can it die and be left running?

    writer.pl instantly dies a couple of times.

    How can it die more than once? What's the error message? Why don't you print the cause of the error ($!) when you call die?

      $ perl reader.pl [in separate terminal] $ perl writer.pl [runs for a while] Could not connect $ perl writer.pl Could not connect $ perl writer.pl Could not connect $ perl writer.pl Could not connect $ perl writer.pl [runs for a while] Could not connect $ killall perl $ perl reader.pl $ perl writer.pl Could not connect
        Me bad, I thought the server was the writer.
Re: IO::Socket disconnects in loop
by Perlbotics (Archbishop) on Jun 13, 2009 at 19:52 UTC

    Hi, I can confirm your observations (SuSE 11.1, perl v5.10.0). Seems that your writer.pl is just too fast and consumes a lot of system resources. When writer.pl dies, netstat -n lists some 26k of TIME_WAIT connections for port 7070. If the client allows the sever some time to recover (I used a select(undef,undef,undef,0.0001); after the $i++ in writer.pl), then there's no problem. Runs, and runs, and runs,....while netstat reports something around 13k TIME_WAIT connections, so a kind of equilibrium has been reached.

    Change the die() statement in writer.pl to die "Could not connect - $!\n" unless $socket and run writer.pl without the select(...) delay using:

    LANG=C perl writer.pl ; netstat -n | egrep 7070 | wc -l
    After a while, writer.pl dies and you'll see something like:
    Could not connect - Cannot assign requested address 28248
    ...meaning, that there were temporarily too few resources left and netstat reported something around 28k connections (nearly all of them in TIME_WAIT state indicating a proper disconnection plus guard time).
    Update: After a while, resources become available again and you can re-start writer.pl successfully.

    HTH

      That makes sense. Thank you!