如何防止 SIGPIPE(或正确处理它们)
我有一个小型服务器程序,它接受 TCP 或本地 UNIX 套接字上的连接,读取一个简单的命令并(取决于命令)发送回复.
I have a small server program that accepts connections on a TCP or local UNIX socket, reads a simple command and (depending on the command) sends a reply.
问题是客户端可能对答案不感兴趣,有时会提前退出.因此,写入该套接字将导致 SIGPIPE
并使我的服务器崩溃.
The problem is that the client may have no interest in the answer and sometimes exits early. So writing to that socket will cause a SIGPIPE
and make my server crash.
防止此处崩溃的最佳做法是什么?有没有办法检查线路的另一边是否仍在阅读?(select()
在这里似乎不起作用,因为它总是说套接字是可写的).或者我应该使用处理程序捕获 SIGPIPE
并忽略它?
What's the best practice to prevent the crash here? Is there a way to check if the other side of the line is still reading? (select()
doesn't seem to work here as it always says the socket is writable). Or should I just catch the SIGPIPE
with a handler and ignore it?
您通常希望忽略 SIGPIPE
并直接在代码中处理错误.这是因为 C 中的信号处理程序对它们可以做什么有很多限制.
You generally want to ignore the SIGPIPE
and handle the error directly in your code. This is because signal handlers in C have many restrictions on what they can do.
最便携的方法是将 SIGPIPE
处理程序设置为 SIG_IGN
.这将防止任何套接字或管道写入导致 SIGPIPE
信号.
The most portable way to do this is to set the SIGPIPE
handler to SIG_IGN
. This will prevent any socket or pipe write from causing a SIGPIPE
signal.
要忽略 SIGPIPE
信号,请使用以下代码:
To ignore the SIGPIPE
signal, use the following code:
signal(SIGPIPE, SIG_IGN);
如果您使用 send()
调用,另一种选择是使用 MSG_NOSIGNAL
选项,这将改变 SIGPIPE
行为按呼叫关闭.请注意,并非所有操作系统都支持 MSG_NOSIGNAL
标志.
If you're using the send()
call, another option is to use the MSG_NOSIGNAL
option, which will turn the SIGPIPE
behavior off on a per call basis. Note that not all operating systems support the MSG_NOSIGNAL
flag.
最后,您可能还需要考虑在某些操作系统上可以使用 setsockopt()
设置的 SO_SIGNOPIPE
套接字标志.这将防止 SIGPIPE
由仅写入它设置的套接字引起.
Lastly, you may also want to consider the SO_SIGNOPIPE
socket flag that can be set with setsockopt()
on some operating systems. This will prevent SIGPIPE
from being caused by writes just to the sockets it is set on.