I'm doing debugging for a program that uses UDP socket. The program creates a socket but after that due to some other problems the program gets stuck and I cannot kill it properly. So I close the command shell and the process goes into 'defunct' state. I guess the socket has not been released in this process because next time I run the program, during the socket creation, it says 'create : Address already in use'. Of course I can start the experiment again if I reboot the computer (actually a small board, with ubuntu 16.04 installed).
I know everything in linux is file, so there should be the socket file somewhere. and I have read here (https://stackoverflow.com/questions/34873151/how-can-i-delete-a-unix-domain-socket-file-when-i-exit-my-application) that I can unlink the socket(using command unlink) and remove it. Where can I find the socket file and how can I get information about the socket file(after I find it)?
2 Answers
Have a Google for the UDP (and TCP) socket parameter called "REUSEADDR" (or "SO_REUSEADDR" etc.) as well as REUSEPORT (to see the difference).
If you use "REUSEADDR" when you create the UDP socket in your app, then SO_REUSEADDR flag will be set when binding to the port. This means that multiple threads or processes can bind to the same address:port without error (provided they all set the flag). Note that only the last process to bind will receive traffic, taking control from the previous listener (in your case, the dead app).
When designing server apps, it is good practice to set the REUSEADDR flag, to allow for fast restarts of the service, else you sit waiting for the bind to succeed. This will allow you to restart your app, without having to hack the socket files, which should be left to the system to manage.
-
ok, that is a good tip. I'll try later.Chan Kim– Chan Kim2020-11-25 09:31:11 +00:00Commented Nov 25, 2020 at 9:31
I think lsof -iUDP is what you're looking for:
$ sudo lsof -iUDP
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
avahi-dae 726 avahi 12u IPv4 21843 0t0 UDP *:mdns
avahi-dae 726 avahi 13u IPv6 21844 0t0 UDP *:mdns
avahi-dae 726 avahi 14u IPv4 21845 0t0 UDP *:46374
avahi-dae 726 avahi 15u IPv6 21846 0t0 UDP *:34483
NetworkMa 732 root 23u IPv4 32835 0t0 UDP stewbian:bootpc->_gateway:bootps
postgres 848 postgres 8u IPv6 21908 0t0 UDP localhost:58947->localhost:58947
postgres 849 postgres 8u IPv6 21916 0t0 UDP localhost:35817->localhost:35817
postgres 850 postgres 8u IPv6 21912 0t0 UDP localhost:40321->localhost:40321
postgres 858 postgres 8u IPv6 21908 0t0 UDP localhost:58947->localhost:58947
postgres 859 postgres 8u IPv6 21908 0t0 UDP localhost:58947->localhost:58947
postgres 860 postgres 8u IPv6 21908 0t0 UDP localhost:58947->localhost:58947
postgres 861 postgres 8u IPv6 21908 0t0 UDP localhost:58947->localhost:58947
postgres 865 postgres 8u IPv6 21912 0t0 UDP localhost:40321->localhost:40321 0t0 UDP localhost:35817->localhost:35817
postgres 877 postgres 8u IPv6 21916 0t0 UDP localhost:35817->localhost:35817
cups-brow 5729 root 7u IPv4 153431 0t0 UDP *:631
You can see you have the PID and the process name. I suspect that is enough to kill $PID to unbind the address.
-
Hi, thanks. (but I couldn't find the culprit socket with this method. I even tried the Zombie process, but it still gives me Adderss already in use' message.Chan Kim– Chan Kim2020-11-25 09:27:59 +00:00Commented Nov 25, 2020 at 9:27