【发布时间】:2010-09-11 05:49:55
【问题描述】:
我正在使用域套接字从另一个进程获取值,例如 A 从 B 获取值,它工作了几个月。但最近,A 在向 B 发送“发送到”消息时失败,偶尔会出现“errno 111,连接被拒绝”。
我检查了B域套接字绑定文件,它是存在的。我也在另一台机器上做了一些测试,效果也很好。那么,以前有人遇到过这个问题吗?谁能提供一些线索,在这种情况下可能有什么问题?非常感谢。
【问题讨论】:
我正在使用域套接字从另一个进程获取值,例如 A 从 B 获取值,它工作了几个月。但最近,A 在向 B 发送“发送到”消息时失败,偶尔会出现“errno 111,连接被拒绝”。
我检查了B域套接字绑定文件,它是存在的。我也在另一台机器上做了一些测试,效果也很好。那么,以前有人遇到过这个问题吗?谁能提供一些线索,在这种情况下可能有什么问题?非常感谢。
【问题讨论】:
当我在 unix 域套接字中看到此错误时,通常是因为进程 B 没有运行,或者连接路径不匹配。 (如果 B 死了,它会自动重新启动吗?是否有可能在 B 死了但尚未重新启动时发生故障?)。另一种可能性:是否有可能同时运行多个 A 副本?如果 B 的尚未接受的连接队列已满,您可能会收到 ECONNREFUSED 错误。
我建议在strace 下同时运行进程 A 和 B:
strace -o A.log A
或者,如果进程已经在运行,
strace -o B.log -p <process-id-of-B>
还有,
netstat -na
将为您提供系统中存在的所有 unix 域套接字的状态。
【讨论】:
netstat -nap(以 root 身份运行时)还将显示连接到这些套接字的进程。
考虑查看/proc/<pid-B>/fd 并查看B 是否耗尽了文件描述符。如果是这样,您有资源泄漏,需要清理。 UDP 程序应该不是问题,但更有趣的事情已经知道。 lsof 可能是另一个可以使用的工具。
否则,你有其他人的合理建议 - netstat 应该会有所帮助。
【讨论】:
请记住,文件系统中的套接字不会在它们的最后一个描述符关闭时自动删除。此时尝试连接或发送将导致错误。服务器将需要删除文件系统中的套接字才能再次绑定。
【讨论】:
进程 B 不再位于您(可能是 DGRAM)套接字的另一端——可能它已经死了,或者关闭了文件句柄,等等。
sendto(2) 在 linux 上,如果接收端已经死机,则会为 SOCK_DGRAM 或 SOCK_SEQPACKET unix 域套接字返回 ECONNREFUSED。 (SOCK_STREAM unix 套接字不会这样做——它们会返回 ENOTCONN。)
【讨论】: