bind()
如果给定的路径已在文件系统中存在,则会失败并返回EADDRINUSE
错误。因此,在服务器关闭时,需要使用
unlink()
操作删除套接字的文件系统条目,以避免在服务器重新启动时出现EADDRINUSE
错误。然而,这不能总是实现(例如:服务器崩溃)。我发现大多数FAQ、论坛帖子和问答网站都建议,在调用bind()
之前使用unlink()
操作来解决此问题。但在这种情况下,最好知道是否有进程已经绑定到该套接字,然后再进行unlink()
操作。当仍有进程绑定到套接字时执行
unlink()
操作并重新创建侦听套接字不会引发任何错误。但结果是旧的服务器进程仍在运行但无法访问:新套接字掩盖了旧套接字。因此,必须避免这种行为。理想情况下,使用Unix域套接字时,套接字API应该提供与绑定TCP或UDP套接字时相同的“互斥”行为:“如果有进程已经绑定到地址A,则指示不能将套接字S绑定到地址A!”不幸的是,事实并非如此...
有没有办法强制实现这种“互斥”行为?或者,是否可以通过套接字API知道是否有任何进程在系统上将Unix域套接字绑定到此路径?我应该使用套接字API外部的同步原语(例如
flock()
)吗?还是我遗漏了什么?感谢您的建议。
注意:Linux的抽象命名空间Unix套接字似乎解决了这个问题,因为没有文件系统条目可以unlink()
。但是,我编写的服务器旨在具有普适性:它必须针对两种类型的Unix域套接字具有健壮性,因为我不负责选择监听地址。