如何防止SIGPIPE(或妥善处理)

如何防止SIGPIPE(或妥善处理)

我有一个小型服务器程序,它接受TCP或本地UNIX套接字上的连接,读取一个简单的命令,并根据命令发送答复。问题是,客户端有时可能对答案不感兴趣,并且提前退出,因此向该套接字写入将导致SIGPIPE并使我的服务器崩溃。防止坠机的最佳方法是什么?有没有办法检查另一边是否还在读?(select()在这里似乎不起作用,因为它总是说套接字是可写的)。或者我应该用一个处理程序捕获SIGPIPE并忽略它吗?



翻阅古今
浏览 1924回答 3
3回答

www说

您通常希望忽略SIGPIPE并在代码中直接处理错误。这是因为C中的信号处理程序对它们所能做的事情有很多限制。实现此操作的最可移植的方法是设置SIGPIPE处理程序SIG_IGN..这将防止任何套接字或管道写入导致SIGPIPE信号。忽略SIGPIPE信号,使用以下代码:signal(SIGPIPE, SIG_IGN);如果您使用的是send()调用,另一个选项是使用MSG_NOSIGNAL选项,这将使SIGPIPE在每次通话的基础上停止行为。注意,并非所有操作系统都支持MSG_NOSIGNAL旗子。最后,您还可以考虑SO_SIGNOPIPE可以设置的套接字标志setsockopt()在一些操作系统上。这样可以防止SIGPIPE由于只写到它所设置的套接字而引起的。

杨魅力

另一种方法是更改套接字,这样它就不会在write()上生成SIGPIPE。这在库中更为方便,在库中,您可能不希望为SIGPIPE设置全局信号处理程序。在大多数基于BSD的(MacOS,FreeBSD.)系统,(假设您使用的是C/C+),您可以使用以下方法来完成:int set = 1;setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));这样,将返回EPIPE,而不是生成SIGPIPE信号。
打开App,查看更多内容
随时随地看视频慕课网APP