计算机网络笔记:TCP链接关闭过程分析

本文详细对比了close与shutdown两个函数在关闭TCP链接时的不同行为及其应用场景。close通过减少引用计数来间接关闭链接,适用于多进程或多线程环境中;而shutdown能够直接关闭链接并允许指定关闭方向。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、关闭方法

从应用层角度来讲,关闭一个TCP链接主要有两种方法,分别是close函数和shutdown函数,他们的函数原型分别为:

#include <unistd.h>
int close(int sockfd);
#include <sys/socket.h>
int shutdown(int sockfd, int howto);

可以看到两者都以一个套接字描述符为参数,只不过前者的目的是为了关闭一个套接字并释放其系统资源,为了达到这个目的必然要关闭与这个套接字对应的链接;而后者则是为了关闭这个套接字对应的链接,如果要关闭套接字并释放资源,还是要调用close,这就是为什么在调用shutdown之后还是要调用close的原因。

这两者在关闭链接时的行为也存在不同:

(1)使用close关闭一个链接时,只是将其参数sockfd的引用计数减一,只有当引用计数减为0的时候才会真正引发关闭链接的行为;而shutdown关闭一个链接时,会直接关闭其参数sockfd对应的链接;这个不同点导致在多进程或者多线程编程时,close可以保证一个进程关闭了某个共享的套接字描述符时,其他进程仍然能使用该描述符对应的链接,因为close只是将描述符的引用计数减一,并没有引发真正的关闭操作;而一个进程使用shutdown关闭链接时,其他使用这个共享套接字描述符的进程将无法使用这个链接;

(2)close关闭链接无法指定关闭的方向,即无法指定关闭读还是关闭写;而shutdown则可以,其第二个参数howto规定了关闭读还是关闭写,其中SHUT_RD代表关闭读,SHUT_WR代表关闭写,SHUT_RDWR代表关闭读写;

2closeshutdown关闭链接时的具体行为

这里参考http://blog.youkuaiyun.com/russell_tao/article/details/13092727的描述,文中对两者的行为总结的很透彻。这里借用上述文章中的两幅图:

(1)close关闭过程



(2)shutdown关闭过程



(3)、总结

a、从上述两幅图中可以看到无论是shutdown还是close,他们发送FIN后返回的情况都紧跟着TCP四次挥手关闭连接的操作,不同之处在于当设定了SO_LINGER选项以及l_linger值不为0时,close必须等待对方对最后发送的数据包以及FIN包确认后才返回,即close的返回标志着四次挥手中的前两次挥手的完成;而其他正常返回(非发送RST返回的情况)则只完成了四次挥手的第一步,发送了FIN包。

b、套接字选项SO_LINGER的作用是对close返回时是否等待对面的确认FIN包作出规定。该选项可用setsockopt函数设置:

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen)

其中optnameSO_LINGERoptval为设置的选项的值的指针,SO_LINGER选项的值为linger结构体:

struct linger
{
	int l_onoff;	/*表示是否开启选项,0=off, nonzero=on*/
	int l_linger;	/*表示等待的超时时间,POSIX规范里该值的单位为秒*/
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值