我对如何正确关闭套接字文件描述符有疑问。假设服务器在接受新连接时会分叉另一个过程。原始套接字文件描述符为sockfd
,新套接字文件描述符为new_sockfd
。
sockfd = socket(...)
bind(...);
listen(...);
while(1) {
new_sockfd = accept(...);
if(fork() == 0) {
// Child process
dosomething(...);
}
else {
}
}
我的问题是,我们应该将close(sockfd)
和close(new_sockfd)
放在哪里。我在网站上看到了一些示例(http://www.tutorialspoint.com/unix_sockets/socket_quick_guide.htm“处理多个连接”),他们将close(sockfd)
放在if
块中,将close(new_sockfd)
放在else
块中。但是,在fork之后,并不是两个并行运行的进程?如果父进程关闭new_sockfd
,它是否会影响处理套接字的子进程?另外,如果子进程执行close(sockfd)
,这不会影响整个套接字程序吗?
答案 0 :(得分:12)
当进程分叉时,文件描述符在子进程中重复。但是,这些文件描述符彼此不同。关闭子文件中的文件描述符不会影响父文件中的相应文件描述符,反之亦然。
在您的情况下,由于子进程需要接受的套接字new_sockfd
并且父进程继续使用侦听套接字sockfd
,因此子进程应close(sockfd)
(在您的{{1}中阻止;这不会影响父级),父级应该if
(在close(new_sockfd)
区块中;这不会影响子级)。父母和孩子同时运行的事实不会影响这一点。
答案 1 :(得分:2)
父级应关闭已接受的套接字(在else
块中):它在子进程中保持打开状态,直到子进程完成为止,此时它应自行关闭。