解析lwIP的`tcp_fasttmr`函数

12 篇文章 0 订阅
12 篇文章 0 订阅

解析lwIP的tcp_fasttmr函数

1. 引言

在本篇博客中,我们将对lwIP(轻量级的IP)库中的tcp_fasttmr函数进行详细剖析。lwIP是一个用于嵌入式系统的开源TCP/IP协议栈,其主要特点是对系统资源需求极小,能够与各种嵌入式系统配合使用。

这个函数被设计为处理由上层(应用)之前"拒绝"的数据,并在每个TCP_FAST_INTERVAL(250毫秒)发送延迟的ACK或挂起的FIN。它会自动从tcp_tmr()被调用。

2. 函数代码

首先,我们来看一下tcp_fasttmr函数的源代码:

void tcp_fasttmr(void)
{
  struct tcp_pcb *pcb;

  ++tcp_timer_ctr;

tcp_fasttmr_start:
  pcb = tcp_active_pcbs;

  while (pcb != NULL) {
    if (pcb->last_timer != tcp_timer_ctr) {
      struct tcp_pcb *next;
      pcb->last_timer = tcp_timer_ctr;
      /* send delayed ACKs */
      if (pcb->flags & TF_ACK_DELAY) {
        LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
        tcp_ack_now(pcb);
        tcp_output(pcb);
        tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
      }
      /* send pending FIN */
      if (pcb->flags & TF_CLOSEPEND) {
        LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: pending FIN\n"));
        tcp_clear_flags(pcb, TF_CLOSEPEND);
        tcp_close_shutdown_fin(pcb);
      }

      next = pcb->next;

      /* If there is data which was previously "refused" by upper layer */
      if (pcb->refused_data != NULL) {
        tcp_active_pcbs_changed = 0;
        tcp_process_refused_data(pcb);
        if (tcp_active_pcbs_changed) {
          /* application callback has changed the pcb list: restart the loop */
          goto tcp_fasttmr_start;
        }
      }
      pcb = next;
    } else {
      pcb = pcb->next;
    }
  }
}

3. 函数参数解析

tcp_fasttmr函数没有参数,但是它使用了一些全局变量。让我们详细了解一下这些全局变量:

  • struct tcp_pcb *pcb;:这是一个指向tcp_pcb结构的指针,用于描述一个TCP连接的状态。这个结构包含了许多字段,包括用于跟踪连接的各种状态(如超时,重试等)的标志,以及用于发送和接收数据的缓冲区等。

  • tcp_timer_ctr:这个变量用于跟踪tcp_fasttmr函数被调用的次数。每当函数被调用时,就会使这个计数器加一。

4. 函数逻辑解析

函数的主要逻辑是一个循环,对tcp_active_pcbs链表中的每一个pcb进行处理。以下是主要步骤:

  1. 初始化:函数首先通过tcp_active_pcbs获得链表的头部pcb

  2. 处理每个pcb:然后,函数进入一个while循环,对链表中的每一个pcb进行处理。

  3. 检查并处理ACK延迟:如果pcb的标志有TF_ACK_DELAY,它会立即发送ACK(通过tcp_ack_now函数),然后将数据输出到网络(通过tcp_output函数),最后清除TF_ACK_DELAYTF_ACK_NOW标志。

  4. 检查并处理挂起的FIN:如果pcb的标志有TF_CLOSEPEND,它会清除TF_CLOSEPEND标志,并通过tcp_close_shutdown_fin函数发送FIN。

  5. 处理之前被拒绝的数据:如果pcb有被之前被拒绝的数据(pcb->refused_data != NULL),它会调用tcp_process_refused_data函数来处理这些数据。如果在处理这些数据的过程中,tcp_active_pcbs链表发生了改变(tcp_active_pcbs_changed变为1),那么函数将重新开始循环(通过goto tcp_fasttmr_start;实现)。

5. 结论

通过对tcp_fasttmr函数的分析,我们可以看出lwIP如何处理TCP协议中的一些核心任务,包括发送延迟的ACK,处理挂起的FIN,以及处理之前被上层拒绝的数据。这个函数的设计充分体现了lwIP对于嵌入式系统资源紧张的考虑,通过精细化的控制和状态管理,尽可能地减少了系统资源的消耗。

参考文献

  1. lwIP - A Lightweight TCP/IP stack ↗
  2. lwIP Wiki ↗

希望这篇博客对你有所帮助。如果有任何疑问或者需要进一步的讨论,欢迎在下方留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值