zoukankan      html  css  js  c++  java
  • TCP定时器 之 FIN_WAIT_2定时器

    当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定时器;

     1 void tcp_close(struct sock *sk, long timeout)
     2 {
     3     if (sk->sk_state == TCP_FIN_WAIT2) {
     4         struct tcp_sock *tp = tcp_sk(sk);
     5         if (tp->linger2 < 0) {
     6             tcp_set_state(sk, TCP_CLOSE);
     7             tcp_send_active_reset(sk, GFP_ATOMIC);
     8             __NET_INC_STATS(sock_net(sk),
     9                     LINUX_MIB_TCPABORTONLINGER);
    10         } else {
    11             const int tmo = tcp_fin_time(sk);
    12 
    13             if (tmo > TCP_TIMEWAIT_LEN) {
    14                 inet_csk_reset_keepalive_timer(sk,
    15                         tmo - TCP_TIMEWAIT_LEN);
    16             } else {
    17                 tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
    18                 goto out;
    19             }
    20         }
    21     }
    22 }

    定时器回调函数:

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

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

     1 static void tcp_keepalive_timer (unsigned long data)
     2 {
     3     /* 省略部分代码 */
     4 
     5     /* 处于fin_wait2且socket即将关闭,用作FIN_WAIT_2定时器 */
     6     if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) {
     7 
     8         /* 停留在FIN_WAIT_2的停留时间>=0 */
     9         if (tp->linger2 >= 0) {
    10             /* 获取在FIN_WAIT_2时间与TIMEWAIT时间差 */
    11             const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN;
    12 
    13             /* 时间差>0,则进入TIME_WAIT状态 */
    14             if (tmo > 0) {
    15                 tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
    16                 goto out;
    17             }
    18         }
    19 
    20         /* 发送rst */
    21         tcp_send_active_reset(sk, GFP_ATOMIC);
    22         goto death;
    23     }
    24 
    25     /* 省略部分代码 */
    26 }

    tcp_time_wait后续补充;

  • 相关阅读:
    Dockerfile构建基础镜像为alpine的jdk1.8镜像
    app测试01_app测试漫谈
    ES基本操作命令
    springboot 前后端日期json格式化
    降维处理PCA
    分析鸢尾花数据集
    Python--matplotlib绘图可视化知识点整理
    模拟股票预期收益案例源代码
    np.random.normal()正态分布
    pandas
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/11749479.html
Copyright © 2011-2022 走看看