2011-03-04 136 views
3

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

*。 SIGPIPE显得非常随机。它可以是确定性的吗?

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

**。第二轮测试是从客户端向服务器发送40000条(25个字符)的消息(总数据为1MB),然后服务器响应它实际收到的数据的总大小。客户端以严格的循环方式发送数据,并且在服务器上有一个单一的接收呼叫。它仅适用于发送总数据的最大1200字节,而且还有非确定性SIGPIPE,现在大约70%(非常糟糕)。

有人可以在我的设计中提出一些改进(可能它会在服务器上)。要求客户端应能够在向服务器发送单个套接字连接之后发送中等到非常高的数据量(每个消息约25个字符)。 我有一种感觉,多次发送反对单一接收将始终是有损和非常低效。我们是否可以合并消息并只发送一个send()操作。这是唯一的方法吗?

回答

7

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

signal(SIGPIPE, SIG_IGN); 

或者,您可以禁用插槽SIGPIPE:

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

此外,数据量你提都不会很高。可能有某处导致连接意外关闭的错误,并提供SIGPIPE。

+1

请注意,SO_NOSIGPIPE不可移植。看到这里:http://stackoverflow.com/questions/108183/how-to-prevent-sigpipes-or-handle-them-properly – 2013-06-18 17:26:19

1

SIGPIPE因为您试图写入已关闭的套接字而引发。这确实表明一个可能的错误,所以请检查你的应用程序,以了解它为什么会发生,并尝试首先修复它。

试图只屏蔽SIGPIPE并不是一个好主意,因为您不知道信号来自哪里,您可能会屏蔽其他来源的错误。在多线程环境中,信号是一个可怕的解决方案。

在极少数情况下,您无法避免这种情况,您可以屏蔽发送信号。如果您将MSG_NOSIGNAL标志设置为send()/sendto(),则会阻止引发SIGPIPE。如果确实触发此错误,则send()返回-1,errno将设置为EPIPE。清洁和简单。详情请参阅man send