我在两个系统上测试了相同的测试代码(服务器 - 客户端)。在一个我得到一个 SIGPIPE,在另一个我没有得到 SIGPIPE。
测试场景如下所示:
客户
- 连接到服务器
- 从服务器接收数据
- 发送数据
- 关闭套接字
服务器
- 接受来自服务器的连接
- 向客户端发送数据
- 接收数据
- 发送数据
- 关闭套接字
在一个系统中(客户端和服务器在同一系统上运行),SIGPIPE 随机发生在客户端或服务器端。
但是,在另一个系统中,同样的测试代码不会出现这个问题。
我想知道损坏的管道是否与 TCP 设置有关。
SIGPIPE
如果您尝试写入另一端已经关闭的套接字,则会引发信号。这里有一个竞争条件,如果一端在另一端尝试发送数据的同时关闭套接字 - 可能在发送之前或之后收到关闭通知,这就是为什么SIGPIPE
在一个测试环境中发生而不是另一个。
通常,套接字感知应用程序应该忽略SIGPIPE
,而是同步处理EPIPE
来自send()
.
您还可以忽略套接字中的 SIGPIPE 以防止应用程序崩溃通过此代码:
int set = 1;
setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
其中 sd 是您接收 SIGPIPE 的套接字。