我正在开发一个通过 TCP 连接到服务器的应用程序。
如果由于某种原因关闭了套接字,我最终会进入 SIGPIPE 处理程序。
我该怎么做才能使 recv 和 send 只在断开/关闭的套接字上返回错误?
谢谢
我发现在 OS X 上忽略 SIGPIPE 无效。请改用 SO_NOSIGPIPE。请注意,这是在套接字上设置一次,而不是在每次调用 send() 时请求的 MSG_NOSIGNAL。
int socket = accept (...); /* (or however you're getting the socket) */
int option_value = 1; /* Set NOSIGPIPE to ON */
if (setsockopt (socket, SOL_SOCKET, SO_NOSIGPIPE, &option_value, sizeof (option_value)) < 0) {
perror ("setsockopt(,,SO_NOSIGPIPE)");
}
要忽略信号,请将信号处理程序设置为SIG_IGN
这样做:
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN;
if (-1 == sigaction(SIGPIPE, &sa, NULL))
{
perror("sigaction() failed");
}
SIG_IGN
信号而不是处理它。 send
将返回 -1 并且 errno 将设置为 EPIPE。
忽略其他答案(即)中描述的 SIGPIPEsignal(SIGPIPE, SIG_IGN);
在 OS X 上对我有用。此外,请务必在调试器之外进行测试,如本评论中所述。我正在调试,lldb
它的信号处理正在用 SIGPIPE 终止我的程序,即使我忽略了那个信号。在外面进行测试lldb
工作正常。
使用信号处理程序或忽略它
#include <signal.h>
signal(SIGPIPE, SIG_IGN);
在写入套接字时,首先检查套接字 fd 是否在程序中为正。在外部,您应该检查您是否正在发送有效套接字的指针
你可以无视SIGPIPE
#include <signal.h>
signal(SIGPIPE, SIG_IGN);
或者您可以使用信号处理程序。
signal(SIGPIPE, handler);
void handler(int signal)
{
//("Signal caught");
}