I am on OS X 10.11.6 and trying to run a program that normally listens on UDP port 8008
upon startup.
This program normally also spawns a couple of helper child processes during its operation, but the port is bound by the parent process.
Unfortunately when exiting the program, sometimes the port remains open, even though the program (parent + children) no longer exist.
When this happens, if I try to run the program again it naturally fails with a EADDRINUSE
error, and in these cases no matter what I try, the only solution I found was to reboot the machine.
I'm having a hard time believing that I cannot release the port without a reboot.
Here are some diagnostics that I ran so far (I ran all of these with and without sudo
):
Find the process using port 8008
with lsof
:
$ lsof -i -n -P | grep UDP | grep 8008
But surprisingly doesn't return any results.
However, I had more luck with netstat
:
$ netstat -tulnvp udp | grep 8008 udp4 0 0 *.8008 *.* 196724 9216 47205 0
So, the port is indeed bound, and the culprit is pid 47205
, however:
$ ps aux | grep 47205
Doesn't return anything. The same thing for PIDs 47206
and 47207
(most certainly the PIDs assigned to the children). I also tried other variations of the grep
(program name, path, etc).
I also looked for any process reporting 47205
as its parent:
$ ps -axo pid,ppid,command | grep 47205
So the children processes are also clearly dead.
Not being able to kill
anything, I tried to SIGHUP launchd
in the hope that it might remove any zombie child processes:
$ sudo kill HUP 1 $ sudo kill -s HUP 1
But alas, netstat
still shows the port bound.
Lastly, I tried to restart the loopback interface:
$ sudo ifconfig lo down $ sudo ifconfig lo up
But again, to no effect.
I have waited several hours since the program last ran, so I'm pretty sure any timeout would have happened by now, but the port just won't get released.
Any ideas on how to force release the port without a reboot?
Edit:
You can find out what is running on a specific port by running the command lsof -i with the port number, :<PortNumber> .
In your code, after you create the socket, but before the bind
call, invoke the following:
int val = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
Then call bind
. The above will allow the socket bind to succeed even if the port is in use.
Two processes, attempting a recvfrom
on the same port, will result in one of the processes receiving the packet, but not the other. And it's not deterministic which one will. So make sure you don't actually have two processes legitimately running and sharing the port.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With