【问题标题】:TCP Send does not return cause crashing processTCP 发送不返回导致进程崩溃
【发布时间】:2010-11-22 18:10:33
【问题描述】:
如果连接了 tcp 服务器和客户端,我想确定客户端何时不再连接。我想我可以通过尝试向客户端发送消息来简单地做到这一点,一旦 send() 返回 -1,我就可以拆除套接字。这个实现可以在 Windows 上找到,但是当我尝试在带有 BSD 套接字的 Linux 上执行此操作时,如果客户端不再连接,则在服务器端应用程序上调用 send() 会导致我的服务器应用程序崩溃。它甚至不返回-1 ...只是终止程序。
请解释为什么会发生这种情况。提前致谢!
【问题讨论】:
标签:
tcp
sockets
crash
send
【解决方案1】:
这是由 SIGPIPE 信号引起的。见send(2):
如果出现以下情况,send() 函数将失败:
[EPIPE]
套接字关闭以进行写入,或者套接字处于连接模式并且不再连接。在后一种情况下,如果套接字是 SOCK_STREAM 或 SOCK_SEQPACKET 类型且未设置 MSG_NOSIGNAL 标志,则会向调用线程生成 SIGPIPE 信号。
您可以通过在 send() 调用上使用 MSG_NOSIGNAL 标志来避免这种情况,或者通过在程序开头使用 signal(SIGPIPE, SIG_IGN) 忽略 SIGPIPE 信号。然后send() 函数将返回-1 并将errno 设置为EPIPE 在这种情况下。
【解决方案2】:
您需要忽略 SIGPIPE 信号。如果在套接字上发生写入错误,您的进程将获得 SIGPIPE,并且该信号的默认行为是终止您的进程。
在 *nix 上编写您通常想要的网络代码:
signal(SIGPIPE,SIG_IGN);