4

我正在设计和测试基于 TCP 套接字(Internet 域)的客户端服务器程序。目前,我正在本地机器上对其进行测试,但无法理解以下有关 SIGPIPE 的内容。

*。SIGPIPE 非常随机地出现。它可以是确定性的吗?

第一个测试涉及来自客户端的单个小(25 个字符)发送操作和相应的服务器接收。相同的代码,在同一台机器上是否成功运行(SIGPIPE)完全不受我的控制。失败率约为 45% 次(相当高)。那么,我可以以任何方式调整机器以尽量减少这种情况。

**。第二轮测试是从客户端向服务器发送 40000 条小消息(25 个字符)(总共 1MB 的数据),然后服务器以它实际接收到的数据的总大小进行响应。客户端在一个紧密的循环中发送数据,并且在服务器上有一个 SINGLE 接收调用。它仅适用于最多发送 1200 字节的总数据,并且再次存在这些不确定的 SIGPIPE,现在大约 70% 次(真的很糟糕)。

有人可以建议对我的设计进行一些改进(可能会在服务器上)。要求是在与服务器建立单个套接字连接后,客户端应该能够发送中等到非常大量的数据(同样每条消息大约 25 个字符)。我有一种感觉,针对单个接收的多次发送总是有损且效率很低。我们是否应该仅在一个 send() 操作中组合消息并发送。这是唯一的出路吗?

4

2 回答 2

8

当您尝试写入未连接的管道/套接字时,会发送 SIGPIPE。为信号安装处理程序将使 send() 返回错误。

signal(SIGPIPE, SIG_IGN);

或者,您可以为套接字禁用 SIGPIPE:

int n = 1;
setsockopt(thesocket, SOL_SOCKET, SO_NOSIGPIPE, &n, sizeof(n));

另外,您提到的数据量不是很高。可能某处有一个错误导致您的连接意外关闭,并给出一个 SIGPIPE。

于 2011-03-04T17:16:25.743 回答
2

引发 SIGPIPE 是因为您试图写入已关闭的套接字。这确实表明可能存在错误,因此请检查您的应用程序以了解它发生的原因并尝试首先修复它。

尝试仅屏蔽 SIGPIPE 不是一个好主意,因为您并不真正知道信号来自何处,并且您可能会屏蔽此错误的其他来源。在多线程环境中,信号是一个可怕的解决方案。

在极少数情况下,如果您无法避免这种情况,您可以屏蔽发送时的信号。如果您在/上设置MSG_NOSIGNAL标志,它将防止被提升。如果您确实触发了此错误,则返回 -1 并将 设置为. 干净又容易。详情请参阅。send()sendto()SIGPIPEsend()errnoEPIPEman send

于 2015-01-27T12:56:21.073 回答