我有一个多线程客户端 - 服务器应用程序。第一个线程是一个“侦听器”,它将客户端添加到文件描述符数组中:
while (1) {
if ((connfd = accept(listenfd_service, (struct sockaddr *) &cliaddr, &clilen)) > 0) {
printf("service connected...\n");
int i;
for (i = 0; i < MAX_SERVICES; i++) {
if (service_sockets[i] == -1) {
service_sockets[i] = connfd;
break;
}
}
}
}
问题在于,当我使用Ctrl + C终止客户端并运行以下行
时for (j = 0; j < MAX_SERVICES; j++) {
if (service_sockets[j] != -1) {
int test = write(service_sockets[j], c, 72);
if (test == -1) {
service_sockets[j] = -1;
}
}
}
我在'test'变量中得到72。如果我第二次尝试运行这些行,我会得到一个SIGPIPE信号。
答案 0 :(得分:4)
这是正常和预期的行为。当客户端退出时,服务器不会立即发现,正常情况下,当没有数据通过网络连接时,没有数据被传输。相反,下次服务器发送数据时,它将发送一个数据包(你成功写入72个字节),客户机(如果操作系统仍在运行)将响应一个&#34;连接复位&#34;信息。这将导致服务器OS关闭其连接的末尾,当服务器下一次写入套接字时导致SIGPIPE / EPIPE。
处理此问题的常规方法是忽略SIGPIPE信号,并处理写入返回EPIPE错误。几乎任何处理多个连接并且可能有一个消失但其他连接仍然有用的过程需要忽略SIGPIPE。