人们的视线总是会指向那些他们有兴趣靠近、试探、寻找或者拥有的东西。---摘自:《人生十二堂课》
当一个TCP连接终止时,需要调用close或者shutdown函数来关闭对应的套接字。那么对于这两个关闭接口,各自适用于什么情况呢,有什么不同呢?以及如何通过套接字属性控制它们产生不同的行为呢?
下面我们就来详细说一说close以及shutdown函数的用法以及它们的区别:
close:关闭套接字
#include <unistd.h>
int close(int sockfd);
返回值:成功:0 出错:-1
参数:sockfd:要关闭的套接字描述符
功能:close一个TCP套接字的默认行为是把该套接口做上“已关闭”标记,并立即返回到进程。
这个套接字不能再为进程所用:它不能作为read或write函数的第一个参数。但TCP将试图发送已在发送队列中待发的任何数据,然后按正常的TCP连接终止序列进行操作(四次挥手)。图示如下图1:
图1:调用close函数执行过程
为了更好的理解close函数的功能,我们需要引用一个“描述符引用计数”的概念。
描述符引用计数:
对于套接字是和linux文件一样有“引用计数”的属性的,如果一个服务器通过fork函数创建子进程来对已连接套接字(sockfd)进行处理,那么当它调用完fork后,已连接套接字描述符(sockfd)的引用计数就从一变成了二(类似于硬连接)。对sockfd调用close将使其引用计数的值从二减为一。并不会触发TCP的四次挥手函数。只有当套接字的引用计数为0时,才会关闭套接字触发TCP的四次挥手。
通过上面介绍我们可以分析出close函数有两个局限:
- close把描述符的引用计数减一,仅在该计数变为0时,才关闭套接字。
- close终止读和写两个方向的数据传送。