davies has asked for the wisdom of the Perl Monks concerning the following question:
I have a client/server pair of scripts that work fine. There is a minor issue on Linux that I want to solve. After running the client from a Windows box, all works as expected, but if the client is run twice in quick succession on Linux, the second attempt results in a message on the client that the server is not responding. netstat reveals that there is still a socket open on the client, although there is a specific close $socket in both the server and client. I have tried restricting this to the client only and have tried both $socket->close and $socket->shutdown(2). I have found a SO_LINGER option with little documentation and have tried setting that to zero. The time on Linux for the socket to reset seems to be of the order of a minute. What should I try next, please? The client code follows; the server code is not very different & can be posted if desired.
use strict; use warnings; use IO::Socket; use sigtrap qw/handler signal_handler normal-signals/; use constant SERVER => 'dns'; use constant PORT => 31416; my $EOL = "\015\012"; my $SENTINEL = '.' . $EOL; die 'Which machine do you want to wake?' unless scalar @ARGV; my $socket = IO::Socket::INET->new( Proto => 'tcp', # protocol PeerAddr => SERVER, # Address or name of server PeerPort => PORT, # port of server ) or die "Server <" . SERVER . "> not responding: <$!>"; $socket->autoflush(1); # Send immediately $socket->setsockopt( SOL_SOCKET, SO_LINGER, 0 ); while (@ARGV) { print $socket (shift @ARGV) . $EOL; # Send to Server while (my $res = <$socket>) { # Receive result from server last if ($res eq $SENTINEL); # Close if sentinel received print $res; # Print the result } } $socket->shutdown(2) or warn $!; sub signal_handler { close $socket or warn $!; }
Regards,
John Davies
Update: The socket is in TIME_WAIT state on the client. No socket appears on the server. The server does not fork, simply sending an etherwake packet to the MAC of any machine(s) named in the args & looping until it responds to ping or reaches a timeout I have set. I see that Reuse is now deprecated and have changed the code to reuse both the addr and the port, both on the server and the client. The only change this makes to the behaviour is that, previously, the port was in TIME_WAIT until a minute had passed or another connection request was made and refused. Now, when the connection is refused, the port remains in TIME_WAIT. A further connection attempt, as previously, still succeeds, but the result is that there can now be multiple copies of the port in TIME_WAIT state. Also, the connection is refused for at least a much longer time than the minute experienced previously. I think I preferred the previous version. :-) My reading (thanks for all the references) leads me to the conclusion that this is the intended behaviour and that I should live with it. I'd rather not, if possible. Experimenting with multiple clients leads me to conclude that this IS a server side problem, as the symptoms move from client to client.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: IO::Socket persisting on Linux despite being closed
by trippledubs (Deacon) on Oct 25, 2018 at 19:15 UTC | |
|
Re: IO::Socket persisting on Linux despite being closed
by superfrink (Curate) on Oct 25, 2018 at 19:12 UTC | |
by Anonymous Monk on Oct 25, 2018 at 20:16 UTC | |
|
Re: IO::Socket persisting on Linux despite being closed
by StuLong (Acolyte) on Oct 25, 2018 at 20:25 UTC | |
|
Re: IO::Socket persisting on Linux despite being closed (updated)
by localshop (Monk) on Oct 27, 2018 at 20:25 UTC | |
|
Re: IO::Socket persisting on Linux despite being closed
by Anonymous Monk on Oct 25, 2018 at 19:39 UTC | |
|
Re: IO::Socket persisting on Linux despite being closed (updated)
by Anonymous Monk on Oct 26, 2018 at 19:24 UTC | |
|
Re: IO::Socket persisting on Linux despite being closed (updated: HTTP::Server::Simple)
by Anonymous Monk on Oct 26, 2018 at 12:06 UTC |