lwip协议栈中超时定时器实现原理

1,超时定时器存在的目的:

tcpip协议中存在很多需要定时处理的任务,包括一次性超时处理和周期性超时处理。

以tcp传输为例,每条连接总共需要建立七个定时器,依次为:

1)“连接建立”定时器。

如果建立连接启动后75秒内没收到响应,则中止建立。

2)“重传”定时器

在tcp发送某个数据段时设定,如果定时器超时了还没接收到对端的确认,则重传数据段。重传定时器值是动态计算的,与          RTT的估算密切相关,且还取决于该报文已被重传的次数。

3)“延迟ACK”定时器

tcp收到必须确认但无需马上发出确认的数据时设定, 如果在200ms内,有数据要在该连接上发送,延迟的ACK随数据一并发          送会对端,若200ms后仍未发出,则定时器超时,此时需要发送一个立即确认。

4)“持续”定时器

在连接对端通知接收窗口为0(缓存无足够空间),阻止发送端继续发送数据时设定。发送端停止发送数据,启动持续定时                  器,超时后向对端发送1字节的数据,判断对端接收窗是否已打开。

5)“保活”定时器

定时器在tcp控制块的so_options字段设置了SOF_KEEPALIVE选项时生效。如果连接的空闲时间超过2小时,保活定时器超             时,此时向对端发送连接探测报文,强迫对端响应。如果收到响应,tcp可确认对端主机工作正常,如果收到RST复位响应,可确                 认对端主机已重启,如果连续若干次保活测试都未收到响应,则tcp假定对端主机已崩溃,但无法区分是主机故障还是线路故障。

6)“FIN_WAIT_2”定时器

7)“TIME_WAIT”定时器(也称2MSL定时器)

2,lwip中超时定时器设计架构:

这里不讨论各个定时器与tcp协议有关的超时如何处理,只讲超时定时器本身的设计。

在lwip中,超时定时器代码实现在 src/core/timers.c中

超时定时器是按链表的形式进行组织的,并且按时间长短进行排序,时间最短的永远在最前面。定时器使用结构体struct sys_timeo进行定义,结构体定义如下:

struct sys_timeo {

struct sys_timeo *next;      //指向下一个定时器

u32_t time;                        //定时值(ms),在加入链表时这个值会进行调整

sys_timeout_handler h;    //定时器回调函数

void *arg;                          //回调函数传入参数

#if LWIP_DEBUG_TIMERNAMES

const char* handler_name;            //回调函数名称,调试用

#endif /* LWIP_DEBUG_TIMERNAMES */

};

添加超时定时器,函数如下:

void  sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)

{

struct sys_timeo *timeout, *t;

/* 每个定时器都从对应的内存池中分配数据结构 */

timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT);

if (timeout == NULL) {

LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL);

return;

}

timeout->next = NULL;

timeout->h = handler;

timeout->arg = arg;

timeout->time = msecs;

#if LWIP_DEBUG_TIMERNAMES

timeout->handler_name = handler_name;

LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n",

(void *)timeout, msecs, handler_name, (void *)arg));

#endif /* LWIP_DEBUG_TIMERNAMES */

/* 如果创建的是第一个定时器,则不用特殊处理,next_timeout是一个全局指针,指向定时器链表中第一个定时器 */

if (next_timeout == NULL) {

next_timeout = timeout;

return;

}

/* 从第二个定时器开始就要添加到链表中,添加原则是定时最短的定时器始终在前面,如果新添加的定时器时长小于当前链首

定时器,则新添加的定时器成为链首,旧的链首定时器的定时值要减去新链首定时器定时值,这样旧定时器时长不变,如果新

添加的定时器大于等于当前链首定时器的时长,则要在整个链表里逐个比较,最终将其插入到比其短的定时器之后,比其长的

定时器之前,当然其后定时器的定时值也要进行调整,其前的定时器无需调整 */

if (next_timeout->time > msecs) {

next_timeout->time -= msecs;

timeout->next = next_timeout;

next_timeout = timeout;

} else {

for(t = next_timeout; t != NULL; t = t->next) {

timeout->time -= t->time;

if (t->next == NULL || t->next->time > timeout->time) {

if (t->next != NULL) {

t->next->time -= timeout->time;

}

timeout->next = t->next;

t->next = timeout;

break;

}

}

}

}

链表中定时器总是按时长升序进行排列,其定时值调整算法为:

Timer(x). time = Timer(x-1).time + Timer(x-2).time + ......
     假如有4个定时器,如下:

Timer1.time = 10

Timer2.time = 5

Timer3.time = 20

Timer4time = 10

按1-4顺序都添加到链表中后,定时器值如下:

Timer1.time = 5

Timer2.time = 5

Timer3.time = 10

Timer4.time = 0

链接关系变为:

Timer2.next = Timer1

Timer1.next = Timer4

Timer4.next = Timer3

Timer3.next = NULL

此时,全局指针变量next_timeout指向Timer2。

3,lwip中超时定时器应用:

不管是否有os支持,超时定时器都可以使用。lwip中如下两个函数可以实现对超时的处理:

void sys_check_timeouts(void)

裸机应用程序在外部周期性调用该函数,每次进来检查定时器链表上定时最短的定时器是否到期,如果没有到期,直接退出该函数,否则,执行该定时器回调函数,并从链表上删除该定时器,然后继续检查下一个定时器,直到没有一个定时器到期退出

void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)

这个函数可在os线程中循环调用,主要是等待mbox消息,并可阻塞,如果等待mbox时超时,则会同时执行超时事件处理,即调用定时器回调函数,如果一直没有mbox消息,则会永久性地循环将所有超时定时器检查一遍,一举两得。

lwip中tcpip线程就是靠这种方法,即处理了上层及底层的mbox消息,同时处理了所有需要定时处理的事件。

lwip协议栈中超时定时器实现原理相关推荐

  1. 深入浅出地理解STM32中的定时器工作原理

    深入浅出地理解STM32中的定时器工作原理 一.如何实现延时 1 纯硬件电路 2 纯软件编程 3 可编程定时/计数器 二.可编程定时/计数器有哪些功能? 三.STM32F103 的定时器有哪些 1 基 ...

  2. lwip路由实现_TCP超时与重传《LwIP协议栈源码详解——TCP/IP协议的实现》

    在TCP两端交互过程中,数据和确认都有可能丢失.TCP通过在发送时设置一个定时器来解决这种问题.如果当定时器溢出时还没有收到确认,它就重传该数据.对任何TCP协议实现而言,怎样决定超时间隔和如何确定重 ...

  3. 嵌入式操作系统内核原理和开发(实时系统中的定时器)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 关于定时器的内容,其实我们之前也讨论过,也书写过相应的代码,但是表达得比较晦涩,效率也比较低. ...

  4. lwip协议栈在linux运行,LwIP协议栈在uCOS II下的实现

    1.概述: LwIP协议栈在设计时就考虑到了将来的移植问题,因此把所有与硬件.OS.编译器相关的部份独立出来,放在ucosii&LwIPsource etlwiparch目录下.因此LwIP在 ...

  5. LWIP协议栈设计与实现笔记:

    LWIP协议栈设计与实现笔记 一.进程模型:采用何种方法把系统分成不同的进程. TCP/IP协议族的每一个协议作为一个独立的进程存在.此模型必须符合协议的每一层,同时必须指定协议之间的通讯点. 优势: ...

  6. c语言定时器作用,Go语言定时器实现原理及作用

    对于任何一个正在运行的应用,如何获取准确的绝对时间都非常重要,但是在一个分布式系统中我们很难保证各个节点上绝对时间的一致性,哪怕通过 NTP 这种标准的对时协议也只能把时间的误差控制在毫秒级,所以相对 ...

  7. LwIP应用笔记(三):在RTOS环境下运行LwIP协议栈

    前言 这篇文章是 LwIP应用笔记(二):无操作系统支持下的RAW API移植 的后续,以下所有内容都是建立在已经完成RAW API移植的前提下.本文可能不会太纠结于代码细节,因为本文的目标并不是演示 ...

  8. ZYNQ lwip协议栈phy芯片自协商连接速度

    一,ZYNQ PS LWIP协议栈遇到的情况说明: 1,vivado2017.4中lwip202支持热插拔,就是慢点,改为自适应立马连上. 2,lwip1401中能快速连上,但是不支持网口热插拔. 3 ...

  9. LwIP协议栈之ICMP(Internet Message Protocal)协议

    在之前主要讲到LWIP了IP层的相关概念(详见本人另外一篇文章:LwIP协议栈之IP协议),其中主要讲解了网络接口(链路层)与IP层(网络层)的数据交互,而数据包是如何从IP层向上级(传输层)传输的并 ...

最新文章

  1. Windows 7使用wubi硬盘安装Ubuntu (文字版)
  2. 全志 系统时间同步到RTC Patch
  3. html:(35):缩进和行高
  4. javascript模板库jsrender加载并缓存外部模板文件
  5. Windows核心编程_关闭Windows
  6. c51单片机跑马灯汇编语言,单片机的跑马灯简单汇编程序
  7. 遥感数字图像处理学习 一、概念及组成
  8. 微信java版s40_微信诺基亚下载
  9. 12306验证码识别V1.5
  10. 互联网深处有趣网站——进阶篇
  11. python微信api_微信公众平台 Python 开发包文档
  12. 两平面平行但不重合的条件是_____怎样证明平行
  13. 大道至简:软件工程实践者的思想(读后感想)
  14. Bootstrap4 div居中
  15. python逻辑回归的主要参数_python机器学习(六)回归算法-逻辑回归
  16. 山东省第三届ACM省赛
  17. hevc中随机访问时非IRAP图像存在三种限制
  18. @keyframes详解与实例
  19. [BZOJ]1933: [Shoi2007]Bookcase 书柜的尺寸 DP
  20. 【源码】声明32位和64位Access、Excel等VBA兼容的API函数的方法

热门文章

  1. 上传漏洞新姿势(限Linux)
  2. Linux下汇编语言学习笔记12 ---
  3. 英文构词法 —— ant、ent 后缀
  4. 火星今天飞抵西非国家寻找埃博拉疫情
  5. sqlserver excel,txt,access等文件的互導
  6. 高级计算机职称考试题,高级职称计算机考试试题
  7. 【控制】《多智能体系统的动力学分析与设计》徐光辉老师-第1章-绪论
  8. 【Matlab 图像】边缘检测算法及效果演示
  9. DFT实际应用-User-Defined Test Points Example
  10. 【PC工具】几个电脑录屏相关软件,手机投屏电脑,电脑显示手机摄像头图像,必须好用无广告!...