客户端断开连接后,是否必须关闭服务器端的套接字?

时间:2017-04-12 11:59:52

标签: c sockets

让我简化我正在处理的代码:

int fd = socket(...);
int client = accept(fd, ...);
while (true) {
    int bytes_read = recv(client, ...);
    if (bytes_read == 0) {
        break;
    }
};

此时我已经知道客户端断开连接(recv返回0)。但我还是要打电话

close(client);

3 个答案:

答案 0 :(得分:9)

当您recv() 0字节时,这是内核通知您远程主机已关闭其发送端连接的方式。它们仍然可以打开套接字并且可以接收您发送的更多数据(但不能回复)。

当您在TCP套接字上调用close()时,您正在做两件事:

  1. 关闭套接字的本地端,让远程主机知道您已完成传输。如果不这样做,您可能会让客户端挂起,等待您发送更多数据。
  2. 关闭文件描述符。这将释放进程打开文件表中的条目。如果不这样做,您就会浪费资源,并且可能会发现自己内存不足或可用的文件描述符。大多数操作系统对进程可以一次打开的文件描述符(或句柄)的数量有一个硬限制。

答案 1 :(得分:1)

您需要关闭描述符以释放绑定到它的资源。

答案 2 :(得分:0)

答案是肯定的。原因是accept()分配内存,close()释放内存。

想象一下理论情况,你的代码在循环中,并且每次调用accept()时,它都会分配1GB的RAM(假装它是一个非常低效的套接字库:-))。无论何时调用close(),它都会释放1GB的RAM。如果你从不调用close(),那么在你的内存耗尽之前,循环会接受多少次()?

当然,accept()只会分配一小块内存,但最终会耗尽内存,除非你对它做了些什么。