Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re^4: Non closing sockets - threads

by igor1212 (Novice)
on Dec 16, 2008 at 08:48 UTC ( [id://730596]=note: print w/replies, xml ) Need Help??


in reply to Re^3: Non closing sockets - threads
in thread Non closing sockets - threads

Hello,

I've done a simple test with windows client and minimum code on server side, as you suggested...

After the client(windows client, putty ...) connects to the server and then you close the client, also the thread on the server is closed.
But, if you interrupt the connection between the windows client and the server, after few seconds the client is closed, but thread on the server remains connected.
Timeout on the server side, was set at 5 sec.

Regards, Igor

Replies are listed 'Best First'.
Re^5: Non closing sockets - threads
by zentara (Archbishop) on Dec 16, 2008 at 14:13 UTC
    Have you tried the IO::Select methods in the thread? Do you get any exceptions? The thread should be able to detect that can_write isn't true, or that some exception has been raised. Maybe lower timeout even further, like 1 second.

    I'm not really a human, but I play one on earth Remember How Lucky You Are
Re^5: Non closing sockets - threads
by gone2015 (Deacon) on Dec 16, 2008 at 21:00 UTC
    But, if you interrupt the connection between the windows client and the server, after few seconds the client is closed, but thread on the server remains connected.

    This is to be expected.

    Once a TCP connection is open it will remain established at each end until it's closed. If one end simply stops sending packets (including closing its end without sending a 'FIN') the other end will wait pretty much indefinitely. (I have tried this with a server running on Linux and Windows XP -- Perl 5.10.0.)

    In this case, the server thread is sat on the while (<$lclient>) waiting for something that will never happen. To avoid this, you need to arrange some form of time-out. The question then is how to establish whether the client has died, or has simply had nothing to say for a while... This rather depends on how the client works.

    I note that the main thread can detect the death of a client when the same $UnitID reconnects.

    Timeout on the server side, was set at 5 sec.

    I believe the timeout value affects only connect and accept.

    Using "SO_KEEPALIVE" at the server end can help, though its usually 2hrs before this starts to worry about the far end having gone quiet -- and then a further 9 x 75secs before it will finally give up.

    Incidentally, passing file handles between threads is generally tricky. In this case:

    while (1) { my $client = $server->accept() ; if (!defined($client)) { ... can do things when accept() times out ... next ; } ; ... prepare to launch thread ... my $thr = threads->new(\&processit, $client)->detach(); } ;
    the GLOB pointed to by $client is duplicated when the new thread is created, so the thread receives a copy of the file handle and $client pointing at it. At the top of the while loop $client is reset, so the file handle for the previous accepted connection is discarded -- meaning that the thread holds the one remaining copy of its file handle, which is what you want ! There are many ways of failing to reach this happy position. (It's not quite so easy to pass a file handle to a pre-existing thread -- but that's another story.)

      If one end simply stops sending packets (including closing its end without sending a 'FIN') the other end will wait pretty much indefinitely. (I have tried this with a server running on Linux and Windows XP -- Perl 5.10.0.)

      Could tell me how, on XP, you can drop the connection between this server:

      #! perl -slw use strict; use IO::Socket; my $server = new IO::Socket::INET( Timeout => 500, Proto => "tcp", LocalPort => 54321, Reuse => 1, Listen => 5 ) or die $^E; my $client = $server->accept; print while <$client>; print "client went away";

      and this client:

      #! perl -slw use strict; use IO::Socket; my $con = IO::Socket::INET->new( 'localhost:54321' ); print $con "ping" while sleep 1; print "client ended";

      Without the server noticing?


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Try moving the client to a different machine. I used:

        #! perl -w use strict; use IO::Socket; my $host = $ARGV[0] ; $|++ ; my $con = IO::Socket::INET->new( "$host\:54321" ) or die "failed to c +onnect: $!" ; while (print $con "ping\n") { print "*" ; sleep 1 ; } ; print "client ended: $!\n";
        Set the two ends going. Disconnect the client machine from whatever network connects them. After a while, the client will give up. The server won't. (You can get the same effect by pulling the plug on the client machine, but I wouldn't recommend that.)

        As far as the server is concerned, this is related to changing the your client to:

        use strict ; use IO::Socket ; $|++ ; my $con = IO::Socket::INET->new( 'localhost:54321' ) or die "failed to + connect: $!" ; for (1..20) { print $con "ping\n" ; print "*" ; sleep 1 ; } ; print " client hanging" ; while (1) { print "." ; sleep 60 ; } ;
        except that when you finally get bored and terminate the client, the OS will close the client end of the connection and the server will get to hear about it.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (4)
As of 2024-04-19 17:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found