sockets – 如何知道任何进程是否绑定到一个Unix域套接字?

我写一个Unix域套接字服务器为Linux。

Unix领域套接字的一个特点我快速发现是,虽然创建一个侦听Unix套接字创建匹配的文件系统条目,关闭套接字不会删除它。此外,在手动删除文件系统条目之前,不可能再次将套接字绑定到同一路径:如果给定的路径已经存在于文件系统中,bind()将失败并返回EADDRINUSE。

因此,套接字的文件系统条目需要在服务器关闭时解除链接(),以避免在服务器重新启动时获得EADDRINUSE。然而,这不总是可以做到(即:服务器崩溃)。最常见的常见问题,论坛帖子,Q& A网站我发现只有建议,作为解决方法,在调用bind()之前unlink()套接字。然而,在这种情况下,需要知道在unlink()之前是否有进程绑定到该套接字。

事实上,unlink()是Unix套接字,而进程仍然绑定到它,然后重新创建侦听套接字不会引发任何错误。因此,旧的服务器进程仍然在运行,但不可达:旧的侦听套接字被新的“掩码”。这种行为必须避免。

理想情况下,使用Unix域套接字,套接字API应该暴露与绑定TCP或UDP套接字时相同的“互斥”行为:“我想将套接字S绑定到地址A;如果进程已绑定到此地址,只是抱怨!不幸的是,这不是这种情况…

有没有办法强制这种“互斥”行为?或者,给定一个文件系统路径,有没有办法知道,通过套接字API,系统上的任何进程是否有一个Unix域套接字绑定到这个路径?我应该使用套接字API外部的同步原语(flock(),…)?还是我错过了什么?

感谢您的建议。

注意:Linux的抽象命名空间Unix套接字似乎解决了这个问题,因为没有文件系统条目来unlink()。然而,我写的服务器旨在是通用的:它必须是鲁棒的两种类型的Unix域套接字,因为我不负责选择侦听地址。

我知道我很晚迟到了,这是很久以前回答,但我只是遇到这种寻找别的东西,我有一个替代的建议。

当您遇到从bind()返回的EADDRINUSE时,您可以输入连接到套接字的错误检查例程。如果连接成功,有一个运行的进程,至少活着足以完成accept()。这使我成为实现你想要实现的最简单和最便携的方式。它的缺点在于,首先创建UDS的服务器可能实际上仍然在运行,但“卡住”某种方式并且无法做一个accept(),所以这个解决方案肯定不是傻瓜,但它是一个步骤在正确的方向我想。

如果connect()失败,然后去连接()端点并再次尝试bind()。

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...