当TCP主动关闭一端调用了close()来执行连接的完全关闭时会执行以下流程,本端发送FIN给对端,对端回复ACK,本端进入FIN_WAIT_2状态,此时只有对端发送了FIN,本端才会进入TIME_WAIT状态,为了防止对端不发送关闭连接的FIN包给本端,将会在进入FIN_WAIT_2状态时,设置一个FIN_WAIT_2定时器,如果该连接超过一定时限,则进入CLOSE状态;

注意:上述是针对close调用完全关闭连接的情况,shutdown执行半关闭不会启动FIN_WAIT_2定时器;

启动定时器:

close系统调用关闭连接最终会调用到tcp_close函数,其中当状态为TCP_FIN_WAIT2时,如果有设置该状态等待时间linger2,且等待时间大于TCP_TIMEWAIT_LEN则启动FIN_WAIT_2定时器;

 void tcp_close(struct sock *sk, long timeout)
{
if (sk->sk_state == TCP_FIN_WAIT2) {
struct tcp_sock *tp = tcp_sk(sk);
if (tp->linger2 < ) {
tcp_set_state(sk, TCP_CLOSE);
tcp_send_active_reset(sk, GFP_ATOMIC);
__NET_INC_STATS(sock_net(sk),
LINUX_MIB_TCPABORTONLINGER);
} else {
const int tmo = tcp_fin_time(sk); if (tmo > TCP_TIMEWAIT_LEN) {
inet_csk_reset_keepalive_timer(sk,
tmo - TCP_TIMEWAIT_LEN);
} else {
tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
goto out;
}
}
}
}

定时器回调函数:

定时器超时会调用tcp_keepalive_timer处理函数,当连接处于FIN_WAIT_2状态,且socket即将关闭,则继续判断FIN等待时间,若有剩余时间,则进入tcp_time_wait函数处理;否则发送rst,并关闭连接;

注:因函数是保活定时器和WAIT_2共用的,我们省略了部分WAIT_2无关代码;

 static void tcp_keepalive_timer (unsigned long data)
{
/* 省略部分代码 */ /* 处于fin_wait2且socket即将关闭,用作FIN_WAIT_2定时器 */
if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) { /* 停留在FIN_WAIT_2的停留时间>=0 */
if (tp->linger2 >= ) {
/* 获取在FIN_WAIT_2时间与TIMEWAIT时间差 */
const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN; /* 时间差>0,则进入TIME_WAIT状态 */
if (tmo > ) {
tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
goto out;
}
} /* 发送rst */
tcp_send_active_reset(sk, GFP_ATOMIC);
goto death;
} /* 省略部分代码 */
}

tcp_time_wait后续补充;

最新文章

  1. nc分析代理服务器
  2. linux系统下本地搭建git服务器
  3. 比较两个Long对象值
  4. [CareerCup] 7.2 Ants on Polygon 多边形上的蚂蚁
  5. POJ 3616 Milking Time (排序+dp)
  6. 这个帖子要收藏,以后用得着--python 实时获取子进程输出
  7. Ⅹ.spring的点点滴滴--IObjectPostProcessor(对象后处理器)
  8. 无法捕获的异常:MissingMethodException
  9. spss
  10. Android学习笔记:Home Screen Widgets(1):大约Widget
  11. Python下的OpenCV学习 01 —— 在Linux下安装OpenCV
  12. http://codeforces.com/problemset/problem/847/E
  13. B2B电商系统开发建设的价格费用取决于哪些要素
  14. Sublime text 添加lua
  15. oracle mysql 比较
  16. jsonp形式的ajax请求:
  17. linux 压缩解压缩命令
  18. Gis数据处理
  19. angularJs中的checkboxs
  20. 解决win10 关键错误开始菜单和cortana无法工作 的问题

热门文章

  1. linux centos 安装mongoDB
  2. MySQL太慢?试试这些诊断思路和工具
  3. MySQL 下载与安装
  4. Nginx如何配置反向代理
  5. 2.bat文件的基本用途
  6. 使用Django的ORM详细操作
  7. Lomsat gelral CodeForces - 600E (树上启发式合并)
  8. zencart产品属性dropmenu select只有一个选择项时自动变成radio单选的解决办法
  9. PHP读取txt文件的内容并赋值给数组的代码
  10. BZOJ3555 [Ctsc2014]企鹅QQ[暴力+字符串hash]