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

the server listener socket seems to be closed when my child thread goes away and I'm using IO:Socket:INET.

If I use the basic Socket methods and raw field descriptors, (i.e.

socket(SERVER, PF_INET, SOCK_STREAM, $proto); . . . while ($paddr = accept(USER, SERVER)) { . . . $thr = threads->create($sub_name, \*USER); . . . }
everything is great; threads come, threads go, the server keeps on chugging.

However, I'd like to use IO:Socket:INET, like this:

my $ServerSocket = new IO::Socket::INET ( LocalPort => $port, Listen => 2, Type => SOCK_STREAM, Reuse => 1, Proto => 'tcp' ); ... while ($clientSocket = $ServerSocket->accept()) { . . . $thr = threads->create( $sub_name, $clientSocket); . . . } Die "END ServerAccept(), $!";
The problem is that when the $sub_name thread returns (NOT exits), I reach the Die and see: "END ServerAccept(), Software caused connection abort", which is obviously a Bad Thing.

If I put in a huge sleep in $sub_name just before returning, other threads can come in, so I'm pretty sure it is the thread cleanup that is closing the server socket. So the question is - how do I prevent this?

Replies are listed 'Best First'.
Re: Server socket closed when thread returns
by liverpole (Monsignor) on Jan 19, 2007 at 00:01 UTC
    Hi pittstown,

    You may need to provide more of a context to figure out what is happening.  And I'd also suggest you consider adding use strict; and use warnings to help you in your debugging task.

    I was unable to make it fail with the following slight rewrite of your program:

    use strict; use warnings; use IO::Socket::INET; use threads; my $port = 19999; my $ServerSocket = new IO::Socket::INET ( LocalPort => $port, Listen => 2, Type => SOCK_STREAM, Reuse => 1, Proto => 'tcp' ); while (my $clientSocket = $ServerSocket->accept()) { my $thr = threads->create(\&child_thread, $clientSocket); } die "END ServerAccept(), $!"; sub child_thread { my ($sock) = @_; print "Accepted client connect\n"; print $sock "Hello client!\n"; chomp(my $from_client = <$sock>); print "Client says '$from_client'\n"; for (my $i = 0; $i < 5; $i++) { # Sleep for a while print "(Still in child thread)\n"; sleep 1; } print "(Child thread finishes)\n"; }

    And here is the client code client.pl I used to test it:

    # Strict use strict; use warnings; # Libraries use IO::Select; use IO::Socket; use Sys::Hostname; # Outgoing port my $port = 19999; my $host = hostname(); my %params = ( 'PeerAddr' => $host, 'PeerPort' => $port, 'Proto' => 'tcp', ); my $sock = new IO::Socket::INET(%params); $sock or die "Could not create socket ($@)\n"; # Declare succcess connecting print "<Connected to server '$host' at port $port>\n"; # Read response from server chomp(my $text = <$sock>); print "Client gets text '$text'\n"; # Send text to the server print $sock "Hi Server!\n"; # Wait for a few seconds sleep 3; # Close the socket close($sock);

    When I run your program, I'm then able to connect using client multiple times without getting any errors:

    C:\Documents and Settings\liverpole> server --- Server --- Accepted client connect Client says 'Hi Server! (Still in child thread) (Still in child thread) (Still in child thread) (Still in child thread) (Still in child thread) (Child thread finishes) Accepted client connect Client says 'Hi Server! (Still in child thread) (Still in child thread) (Still in child thread) (Still in child thread) (Still in child thread) Accepted client connect Client says 'Hi Server! (Still in child thread) (Child thread finishes) (Still in child thread) (Still in child thread) (Still in child thread) (Still in child thread) (Child thread finishes) --- Client --- C:\Documents and Settings\liverpole> client <Connected to server 'golux' at port 19999> Client gets text 'Hello client!' C:\Documents and Settings\liverpole> client <Connected to server 'golux' at port 19999> Client gets text 'Hello client!' C:\Documents and Settings\liverpole> client <Connected to server 'golux' at port 19999> Client gets text 'Hello client!'

    What happens when you run the above programs?  If they work, see what happens running my client program with your server and see what happens.

    If all else fails, please provide more of the context of your own program.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/