【发布时间】:2012-11-13 10:04:56
【问题描述】:
我有一个服务器正在侦听一个 tcp 端口。当有传入连接时,它使用accept() 并使用fork() 生成一个子进程。客户端/子进程从连接中读取一些数据并通过管道将其发送回服务器。在此之后,我想关闭连接。我尝试在客户端进程中使用shutdown() 和close(),但运气不佳。
我检查了shutdown() 和close() 的结果,它们都返回0。显然它们运行顺利。在shutdown() 和close() 都运行后,服务器从子进程接收sigchld。这是在一般基础上处理的,但我更愿意在接收信号之前关闭连接。
任何有关如何执行此操作的建议将不胜感激。
附带说明 close() 已用于关闭整个服务器/客户端程序中不需要的文件描述符和套接字,但现在我不确定它们是否真的被关闭了。
下面是两个代码sn-ps。
首先是程序服务器部分的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的代码sn-p:
//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);
有什么好主意吗?
*编辑: 阅读 cmets 后,我尝试从父进程执行 close(client_s),但它并没有解决我的问题。为了清楚起见,我还在代码 sn-p 中添加了这一行。
【问题讨论】:
-
你省略了有趣的部分:在 else 部分中“关闭一些文件描述符”。
-
""//将客户端添加到客户端列表并关闭一些文件描述符。" , 那么你关闭了哪些文件描述符?你
close(client_s)了吗? -
不,我没有
close(client_s)。是否需要从父进程和客户端关闭文件描述符? -
是的,
fork()ed 进程的两个副本都有文件描述符的副本。当所有套接字都关闭时,套接字将关闭。