我正在对使用 UDP 套接字的程序进行调试。该程序创建了一个套接字,但之后由于一些其他问题,该程序被卡住,我无法正确终止它。因此,我关闭命令 shell,进程进入“失效”状态。我猜想套接字在此过程中尚未释放,因为下次我运行程序时,在套接字创建期间,它会显示“创建:地址已在使用中”。当然,如果我重新启动计算机(实际上是一个小板,安装了ubuntu 16.04),我可以再次开始实验。
我知道linux中的一切都是文件,所以应该在某个地方有套接字文件。我已经读过这里(https://stackoverflow.com/questions/34873151/how-can-i-delete-a-unix-domain-socket-file-when-i-exit-my-application)我可以取消套接字的链接(使用命令unlink
)并将其删除。在哪里可以找到套接字文件以及如何获取有关套接字文件的信息(找到后)?
答案1
Google 提供了 UDP(和 TCP)套接字参数,称为“REUSEADDR”(或“SO_REUSEADDR”等)以及 REUSEPORT(以查看差异)。
如果您在应用程序中创建 UDP 套接字时使用“REUSEADDR”,则绑定到端口时将设置 SO_REUSEADDR 标志。这意味着多个线程或进程可以绑定到同一地址:端口而不会出错(前提是它们都设置了该标志)。请注意,只有最后一个绑定的进程才会接收流量,从而从前一个侦听器(在您的情况下,即已死亡的应用程序)获得控制权。
设计服务器应用程序时,最好设置 REUSEADDR 标志,以允许快速重新启动服务,否则您将等待绑定成功。这将允许您重新启动应用程序,而不必破解套接字文件,这些文件应该留给系统来管理。
答案2
我想lsof -iUDP
这就是你正在寻找的:
$ 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
您可以看到您有 PID 和进程名称。我怀疑这足以kill $PID
解除地址绑定。