关闭后,UNIX域套接字未关闭()

时间:2015-02-18 18:52:50

标签: c sockets unix virtualization qemu

我有一个客户端应用程序通过QMP Unix域套接字与QEMU进程通信。有时在客户端在套接字连接上调用close()之后,' netstat -ap unix'仍然显示它处于CONNECTED状态。我检查close()调用的返回值,并成功返回值为0,但连接似乎仍然挥之不去。

由于QMP并不真正支持其套接字上的多个连接,因此连接到套接字的所有后续调用都会失败,因为它们无限期地等待延迟连接被关闭。

有没有办法确保代码中的套接字真正关闭,是否有办法强制套接字关闭?

3 个答案:

答案 0 :(得分:1)

可能是文件描述符已被dup编辑,fork编辑或泄露。

close之前调用shutdown(sock, SHUT_RDWR)以确保关闭连接。

答案 1 :(得分:0)

您是否尝试过从另一端关闭套接字?它是异步的,但它让双方都有机会确保套接字关闭。

您可以向另一端的侦听器发送一个close命令,让它回收套接字。当套接字关闭时,你最终应该得到一个SIGPIPE。抓住SIGPIPE并关闭套接字的末尾。如果你最终得到EPIPE,那么忽略它。这只意味着你已经收到套接字关闭的通知。

答案 2 :(得分:-1)

您可以通过setsockopt(2)选项尝试SO_LINGER,超时为0.这样,当您关闭套接字时强制关闭,发送RST而不是进入FIN / ACK关闭行为。

SO_LINGER选项的目的是控制在调用函数close(2)时套接字的关闭方式。此选项仅适用于面向连接的协议,如TCP。

内核的默认行为是允许close(2)函数立即返回给调用者。如果可能,将传输和传送任何未发送的TCP / IP数据,但不保证。因为close(2)调用立即将控制权返回给调用者,所以应用程序无法知道最后一位数据是否实际传递。

可以在套接字上启用SO_LINGER选项,以使应用程序在close(2)调用中阻塞,直到所有最终数据都传递到远程端。此外,这确保了呼叫者两端都已确认正常的套接字关闭。如果失败,则会发生指示的选项超时,并且会向调用应用程序返回错误。

可以通过使用不同的SO_LINGER选项值应用最终方案。如果调用应用程序想立即中止通信,则可以在linger结构中设置适当的值。然后,关闭(2)的调用将启动通信链接的中止,丢弃所有未决数据并立即关闭套接字。