我经常看到使用套接字的服务器程序的示例代码。
(为简单起见,这里我不检查诸如socket()或bind()等函数的返回值。)
int sockfd = 0, newsockfd = 0;
struct sockaddr_in address;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bind(sockfd, (struct sockaddr*)&address, sizeof(address));
listen(sockfd, 1);
newsockfd = accept(sockfd, (struct sockaddr*)NULL, NULL);
... do some communication ...
close(newsockfd);
我在网上找到的大多数示例代码都有 close(newsockfd),但没有 close(sockfd)。 我的问题是不关闭sockfd是否真的正确。
如果正确,我想知道为什么。 我的理解是sockfd是文件描述符之一, 似乎没有理由不关闭程序就退出程序。
更具体地说,我想知道,当程序下次运行时,not-closing-sockfd会导致绑定错误(例如,该套接字在使用中...)。
如果您能帮助我,我非常感谢。 谢谢您的宝贵时间。
答案 0 :(得分:4)
由应用程序分配的资源(例如内存或打开的文件描述符(包括套接字))将在程序退出时由现代OS自动释放。因此,如果服务器套接字在整个程序中都应该可用(为了接受连接),则最好不要显式关闭它,而应在应用程序退出时让操作系统执行此操作。
答案 1 :(得分:3)
停止收听时,应始终关闭sockfd。
一些开发人员对不关闭sockfd不太关心的两个原因:
但是,如果您的程序在某个事件上启动了侦听套接字,然后在一段时间后将其关闭并循环,则必须关闭sockfd,以防止在下一次迭代时出现错误EADDRINUSE(地址已在使用中)和内存泄漏。
此外,在其他我没有在此详细说明的情况下,可能会发生错误EADDRINUSE(地址已在使用中)。
答案 2 :(得分:1)
sockfd充当服务器套接字:它仅用于接受越来越多的传入连接。只要您必须接受并处理newsockfd上的新连接,就可以保持sockfd处于打开,绑定和侦听状态,并保持当前连接在您正在从某个对等程序读取/写入的过程中进行。用newsockfd完成后,将其关闭,如果需要,请在sockfd上使用accept()接受一个新的。依此类推。