使用非阻塞套接字获取SIGPIPE - 这是正常的吗?

时间:2014-02-10 20:54:44

标签: c linux sockets signals epoll

我正在用C编写一个基于epoll的网络服务器。当我创建我的套接字以侦听传入的连接时,我使用fcntl使其成为非阻塞。类似地,当传入的连接从客户端到达时,我在对它们执行任何操作之前使其套接字无阻塞,同样对于传出连接的套接字也是如此。

有时我的服务器会收到一个SIGPIPE - 我认为这是我尝试写入客户端关闭的客户端连接时。这对我来说似乎很奇怪;我认为使用非阻塞套接字而不是SIGPIPE,我应该从-1writeECONNRESET的调用中获得errno

有什么我想念的吗?或者即使使用非阻塞套接字同时获得SIGPIPE和错误代码也是正常的(这意味着我应该在我的设置中明确忽略signal(SIGPIPE, SIG_IGN)的信号)?

2 个答案:

答案 0 :(得分:2)

是的,这很正常。如果您写入另一端已关闭连接的套接字(非阻塞或非阻塞),您将获得SIGPIPE或(如果您阻止SIGPIPE信号)错误返回({ {1}})将-1设置为errno

来自EPIPE的手册页:

  

writeEPIPE连接到读取结束的管道或套接字。当发生这种情况时,写入过程也会收到   一个fd信号。 (因此,仅当程序捕获,阻止或忽略此信号时才会看到写返回值。)

POSIX标准在这里:http://pubs.opengroup.org/onlinepubs/009695399/functions/write.html并说:

  

SIGPIPE尝试写入未被任何进程读取的管道或FIFO,或只打开一端的管道或FIFO。 [EPIPE]信号也应发送给线程。

答案 1 :(得分:1)

SIGPIPE是正常的。除了为此目的设置信号处理程序之外的另一个选择是在发送时使用标志MSG_NOSIGNAL。