shutdown()和close()什么都不做

时间:2012-11-13 10:04:56

标签: c sockets shutdown

我有一台服务器正在侦听tcp端口。当有传入连接时,它使用accept()并使用fork()生成子进程。客户端/子进程从连接中读取一些数据,并通过管道将其发送回服务器。在此之后,我想关闭连接。我试图在客户端流程中使用shutdown()close()而没有太多运气。

我检查了shutdown()close()的结果,他们都返回0.所以显然他们顺利运行。运行shutdown()close()后,服务器会从子进程收到sigchld。这是在一般情况下处理,但我更愿意在接收信号之前关闭连接。 关于如何做到这一点的任何建议将非常感激。

旁注close()已被用于在整个服务器/客户端程序中关闭不需要的文件描述符和套接字,但现在我不确定这些是否实际上已关闭。

以下是两个代码段。 首先是程序服务器部分中的accept()fork()

if ((client_s = accept(s, &info.addr, &addrlen)) == -1) {
    //Error handling
}
if ((info.pid = fork()) == -1) {
    //More error handling
}
else if (info.pid == 0) {
    //Closing all unneeded file descriptors

    // Set default signal handler for SIGCHLD
    signal(SIGCHLD, SIG_DFL);

    _exit(clientStatus_main(client_s, info_pipes[1]));
}
else {
    //Adding client to list of clients and closing some file descriptors.
    close(client_s);
}

最后是函数clientStatus_main的代码片段:

//Signal handling
signal(SIGINT, client_sighandler);
signal(SIGTERM, client_sighandler);
signal(SIGKILL, client_sighandler);
signal(SIGHUP, client_sighandler);
signal(SIGCHLD, SIG_DFL);

//Read data from socket
read(socket, &status_packet.type, iLength)
//Do data handling and write back to server
write(info_pipe, &status_packet, status_packet.len)

//Close down socket
res = shutdown(socket, SHUT_RDWR);
addlog(LOG_INFO, "Result of shutdown: %i\n", res); //Write to log
res = close(socket);
addlog(LOG_INFO, "Result of close: %i\n", res);
return (iCount > 0 ? 0 : -1);

有什么好主意吗?

* 编辑:在阅读了我已尝试从父进程执行close(client_s)的评论后,但它没有解决我的问题。为清楚起见,我还在代码段中添加了该行。

2 个答案:

答案 0 :(得分:1)

涉及三个过程:

客户端:连接到父级的侦听套接字。

侦听套接字的父:服务器进程,接受连接并将其移交给孩子。

:服务器进程,通过已建立的连接与客户端进行通信。

建立的连接仅存在于the childthe client之间。 The parent无法检测客户端套接字何时从任何一方关闭。

有两种方式可以通知the parent the child正在关闭连接并终止,要么抓住SIGCHLD信号,要让the child向{{1}发送消息例如,问题中提到的the parent

答案 1 :(得分:0)

这有点令人尴尬,但似乎问题不在于close()shutdown()。 KlasLindbäck的评论和答案让我思考,我进行了一些实验,发现SIGCHLD已发送,因为客户端实际上在子进程同时关闭了连接。

所以我的解决方案受到了KlasLindbäck的建议的启发。子进程通过前面提到的管道发送进程ID,父进程现在可以安全地忽略/阻止从此进程发送的SIGCHLD