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

来源:互联网 发布:python net snmp 编辑:程序博客网 时间:2024/05/17 22:29

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.csdn.net/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规范里该值的单位为秒*/}



原创粉丝点击