假设您有一个应用程序,该应用程序在启动时创建一个 unix 域套接字并开始侦听它。然后,应用程序的任何后续实例都会连接到该套接字,将数据传递到第一个实例并退出(或者如果检测到另一个实例正在运行,则直接退出)。
据我了解,这种套接字在文件系统上表示为文件。假设该文件被随机的第 3 方程序或用户删除。现在,后续进程将无法检测到第一个实例/与第一个实例通信。
第一个可以以某种方式检测到套接字文件的删除然后重新创建它吗?
答案1
您无法重新创建已删除的 Unix 套接字文件。
事实上,您可以创建另一个具有相同路径的套接字文件(通过尝试再次将套接字文件描述符绑定到相同的地址),但是任何尝试连接到它的客户端都会收到“连接被拒绝”而不是连接到首先绑定到它的套接字。
那是因为 Unix 套接字基本上绑定到索引节点,而不是路径。您可以轻松检查您的 netcat 是否支持 Unix 套接字:
nc -lU /tmp/old_sock &
[1] 19241
ln -f /tmp/old_sock /tmp/new_sock; rm /tmp/old_sock
# or mv /tmp/old_sock /tmp/new_sock
echo yup | nc -U /tmp/new_sock
yup
您的程序所能做的就是关闭旧套接字,创建另一个套接字并将其绑定到相同的地址。为了收到文件删除的通知,您可以inotify(7)
在 Linux、kqueue(2)
BSD 上使用,或者只是stat(2)
定期在路径上执行(就像处理任何其他文件一样)。
请注意,Linux 也有“抽象”Unix 套接字——绑定到字节序列[1]而不是任何文件系统对象的套接字,并且不受任何文件样式访问权限的约束,并且不能“删除”或搬到不同的地址。
[1] 您可以将其称为“字符串”,但请注意,与文件系统路径不同,它也可以包含 NUL 字节。