C中的套接字:关闭套接字的正确方法

时间:2018-11-10 10:00:08

标签: c sockets server

我经常看到使用套接字的服务器程序的示例代码。

(为简单起见,这里我不检查诸如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会导致绑定错误(例如,该套接字在使用中...)。

如果您能帮助我,我非常感谢。 谢谢您的宝贵时间。

3 个答案:

答案 0 :(得分:4)

由应用程序分配的资源(例如内存或打开的文件描述符(包括套接字))将在程序退出时由现代OS自动释放。因此,如果服务器套接字在整个程序中都应该可用(为了接受连接),则最好不要显式关闭它,而应在应用程序退出时让操作系统执行此操作。

答案 1 :(得分:3)

停止收听时,应始终关闭sockfd。

一些开发人员对不关闭sockfd不太关心的两个原因:

  • 如果您的程序未关闭而退出,则操作系统将为您关闭sockfd
  • 大多数情况下,服务器始终保持侦听状态(例如:几个月)

但是,如果您的程序在某个事件上启动了侦听套接字,然后在一段时间后将其关闭并循环,则必须关闭sockfd,以防止在下一次迭代时出现错误EADDRINUSE(地址已在使用中)和内存泄漏。

此外,在其他我没有在此详细说明的情况下,可能会发生错误EADDRINUSE(地址已在使用中)。

答案 2 :(得分:1)

sockfd充当服务器套接字:它仅用于接受越来越多的传入连接。只要您必须接受并处理newsockfd上的新连接,就可以保持sockfd处于打开,绑定和侦听状态,并保持当前连接在您正在从某个对等程序读取/写入的过程中进行。用newsockfd完成后,将其关闭,如果需要,请在sockfd上使用accept()接受一个新的。依此类推。

相关问题