我写一个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域套接字,因为我不负责选择侦听地址。