10

如果连接了 tcp 服务器和客户端,我想确定客户端何时不再连接。我想我可以通过尝试向客户端发送消息来简单地做到这一点,一旦 send() 返回 -1,我就可以拆除套接字。这个实现可以在 Windows 上找到,但是当我尝试在带有 BSD 套接字的 Linux 上执行此操作时,如果客户端不再连接,则在服务器端应用程序上调用 send() 会导致我的服务器应用程序崩溃。它甚至不返回-1 ...只是终止程序。

请解释为什么会这样。提前致谢!

4

2 回答 2

17

这是由 SIGPIPE 信号引起的。见send(2)

如果出现以下情况,send() 函数将失败:
[EPIPE] 套接字因写入而关闭,或者套接字处于连接模式且不再连接。在后一种情况下,如果套接字的类型为 SOCK_STREAM 或 SOCK_SEQPACKET 并且未设置 MSG_NOSIGNAL 标志,则向调用线程生成 SIGPIPE 信号。

MSG_NOSIGNAL你可以通过在调用中使用标志来避免这种情况send(),或者在程序开始时忽略SIGPIPE信号signal(SIGPIPE, SIG_IGN)。然后该send()函数将返回 -1 并在这种情况下设置errno为。EPIPE

于 2009-08-25T20:05:36.223 回答
2

您需要忽略 SIGPIPE 信号。如果在套接字上发生写入错误,您的进程将获得 SIGPIPE,并且该信号的默认行为是终止您的进程。在 *nix 上编写您通常想要的网络代码:

signal(SIGPIPE,SIG_IGN);
于 2009-08-25T20:06:14.490 回答