1

I have a script that uses IO::Socket::INET to establish a TCP server

my $socket = new IO::Socket::INET (
LocalHost => '0.0.0.0',
LocalPort => '10010',
Proto => 'tcp',
Listen => 5,
);

If my script crashes or is stopped by the user before it reaches the closure of the server socket, then the next time the script is run it cannot bind to the port as there is still a process listening on the to port

Except from the results netstat -anobp tcp

TCP    0.0.0.0:10010          0.0.0.0:0              LISTENING       22628
[System]

Yes I am using Windows.

A task kill request:

taskkill /f /PID 22628

fails with:

ERROR: The process "22628" not found.

The only way to get around this is to reboot, or increment the listening port. Since I am not a real software developer and can write great code first time that doesn't crash, then I run into this problem a lot.

Also worth noting that this happens only once a client has connected to the server.

Is there a way to stop this from happening (no orphan listen process) or a way of getting rid of orphan?

  • Does the orphan listening port stay forever or does it disappear after a timeout period? If the latter then you probably just need to use the socket option `SO_REUSEADDR`. Maybe this [SO question](https://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t) will help. – Stefan Becker Feb 13 '19 at 03:22
  • i.e. in [IO::Socket::INET](https://metacpan.org/pod/IO::Socket::INET#new-(-[ARGS]-)) terms `->new(..., ReuseAddr => 1, ...);` – Stefan Becker Feb 13 '19 at 03:30
  • Is your problem solved? If yes, then please accept the answer so it will no longer show up as unanswered. Thank you. – Stefan Becker Feb 13 '19 at 19:06

1 Answers1

2

Does the problem go away when you add the following?

On most systems the solution would be:

my $socket = new IO::Socket::INET (
    ...
    ReuseAddr => 1,
    ReusePort => 1,
    ...
);

On systems that do not have SO_REUSEPORT, like Windows, the solution would be:

my $socket = new IO::Socket::INET (
    ...
    ReuseAddr => 1,
    ...
);
Stefan Becker
  • 5,201
  • 9
  • 17
  • 27
  • Thanks for the suggestion, ended up with the error 'Your vendor has not defined Socket macro SO_REUSEPORT, used at C:/Dwimperl/perl/lib/IO/Socket/INET.pm line 194' – orsapihki wiioiv Feb 13 '19 at 20:03
  • Yes, I feared that might happen, because the mentioned SO answer said it is not available on Windows, I just wanted to post the complete standard solution. Please try again after removing `ReusePort => 1`. – Stefan Becker Feb 13 '19 at 20:30
  • With just `ReuseAddr =>1' only I end up with two listening processes ` TCP 0.0.0.0:10009 0.0.0.0:0 LISTENING 13268 [perl.exe] TCP 0.0.0.0:10009 0.0.0.0:0 LISTENING 30004 [System]`. Then when I try and connect the socket is opened, but the script does not see the attempt or traffic. As though the socket has been accepted by the old process. – orsapihki wiioiv Feb 14 '19 at 02:16
  • Then I guess the problem is caused by something else, i.e. you'll need to strip down your server code to the bare minimum that exhibits the problem and add it to the question. Which Perl are your using under WIndows? Have you tried your code with another version, eg. under cygwin or mingw? – Stefan Becker Feb 14 '19 at 03:05