TCP发送不返回导致进程崩溃。

10
如果一个tcp服务器和客户端已经连接,我想确定客户端何时断开连接。 我认为可以通过尝试向客户端发送一条消息来实现这一点,并且一旦send()返回-1,就可以拆除套接字。 这种实现在Windows上运行良好,但是当我尝试在使用BSD套接字的Linux上执行此操作时,如果客户端不再连接,则服务器端应用程序上的send()调用会导致我的服务器应用程序崩溃。 它甚至没有返回-1...只是终止程序。
请解释为什么会发生这种情况。 谢谢!
2个回答

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

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

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

2

您需要忽略SIGPIPE信号。如果套接字上发生写入错误,您的进程会收到SIGPIPE信号,该信号的默认行为是杀死您的进程。 在*nix上编写网络代码时,通常希望:

signal(SIGPIPE,SIG_IGN);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接