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