gpt4 book ai didi

sockets - 如何知道某个进程是否绑定(bind)到 Unix 域套接字?

转载 作者:行者123 更新时间:2023-12-02 18:06:09 26 4
gpt4 key购买 nike

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

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

因此,套接字的文件系统条目需要在服务器关闭时进行 unlink() 处理,以避免在服务器重新启动时获取 EADDRINUSE。然而,这并不总是能做到(即:服务器崩溃)。我发现的大多数常见问题解答、论坛帖子、问答网站仅建议作为一种解决方法,在调用 bind() 之前先 unlink() 套接字。然而,在这种情况下,需要在 unlink()'ing 之前知道进程是否绑定(bind)到此套接字。

事实上,在进程仍绑定(bind)到 Unix 套接字时unlink()'然后重新创建监听套接字不会引发任何错误。然而,结果是旧的服务器进程仍在运行但无法访问:旧的监听套接字被新的监听套接字“屏蔽”。必须避免这种行为。

理想情况下,使用 Unix 域套接字,套接字 API 应该暴露与绑定(bind) TCP 或 UDP 套接字时暴露的相同“互斥”行为:“我想将套接字 S 绑定(bind)到地址 A;如果一个进程已经绑定(bind)到这个地址,只是提示!”不幸的是事实并非如此......

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

感谢您的建议。

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

最佳答案

我知道我参加聚会已经很晚了,而且这个问题很久以前就得到了回答,但我只是在寻找其他东西时遇到了这个问题,并且我有一个替代提案。

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

如果connect()失败然后继续 unlink()端点并尝试 bind()再次。

关于sockets - 如何知道某个进程是否绑定(bind)到 Unix 域套接字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7405932/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com