uip_process运行流程

uip_process(u8_t flag)

(1)if(flag == UIP_UDP_SEND_CONN),若是则goto udp_send;不是则向下执行;

(2)

if(flag == UIP_POLL_REQUEST)

{

if(tcpstateflags== UIP_ESTABLISHED&&!uip_outstanding(uip_connr))如果处于稳定连接状态且没有数据在缓存中等待确认则:

{

①uip_flags = UIP_POLL;

②UIP_APPCALL();

③goto appsend;

}

goto drop;

}

else if(flag == UIP_TIMER)

{

uip_len = 0;

uip_slen = 0;

如果连接处于等待超时关闭状态则增加超时计数器,如果到达超时期限则关闭当前连    接tcpstateflags =UIP_CLOSED;

if(tcpstateflags != UIP_CLOSED) 如果连接不处于关闭状态

{

if(uip_outstanding(uip_connr)&&(timer--== 0)) 已经发送的数据包还未接收                            到对其的ACK,超时计数器减一且超时计数器值为0

{

①如果到达所设定的重发次数则:

tcpstateflags = UIP_CLOSED;关闭当前连接

uip_flags = UIP_TIMEDOUT;通知应用程序超时;

UIP_APPCALL();

设置RST+ACK终止连接标志

goto tcp_send_nodata;

②没有到达设定的重发次数则重传数据:

重置重传计数器

switch(tcpstateflags)根据连接处的不同状态重发不同的数据包

case UIP_SYN_RCVD:

goto tcp_send_synack;重新发送先前发送的SYN+ACK

case UIP_SYN_SENT:

goto tcp_send_syn;重发SYN请求连接

case UIP_ESTABLISHED:

uip_flags = UIP_REXMIT;

UIP_APPCALL(); 调用上层应用程序,通知重新生成数据重发

goto apprexmit;进入重发阶段

case UIP_FIN_WAIT_1:

case UIP_CLOSING:

case UIP_LAST_ACK:

goto tcp_send_finack;重发FIN+ACK关闭连接

}

else if(tcpstateflags) == UIP_ESTABLISHED) 处于稳定连接状态且上次发送的数据                                            接收到正确的ACK,可以继续发送新数据

{

①uip_flags = UIP_POLL;询问应用程序是否有数据要发送

②UIP_APPCALL();调用应用程序产生数据

③goto appsend;发送数据

}

}

goto drop;

}

if(flag == UIP_UDP_TIMER)

{

当前连接的本地端口不为0则

{

①uip_len = uip_slen = 0;

②uip_flags = UIP_POLL;询问应用程序是否有数据要发送

③UIP_UDP_APPCALL();调用应用程序产生数据

④goto udp_send;

}

本地端口为0,表明没有建立DUP连接,则

{

goto drop;

}

}

(3)检查IP帧头中的IP版本及IP头长度是否符合要求:

①不符合:goto drop;丢弃此包

②符合继续向下执行

(4)检查目的IP地址是否为本机地址:

①不是,goto drop;丢弃此包

②是,向下继续执行

(5)if(BUF->proto == UIP_PROTO_TCP)IP上层协议是否为TCP协议

①是,goto tcp_input;进入TCP数据处理模块

②不是,继续向下执行

if(BUF->proto == UIP_PROTO_UDP)IP上层协议是否为UDP协议

①是,goto udp_input;进入UDP数据处理模块

②不是,继续向下执行

if(BUF->proto != UIP_PROTO_ICMP) 不是TCP不是UDP也不是ICMP协议

①goto drop;本机只处理UDP、TCP、ICMP数据包,其它包都将丢弃

运行到此处,表明接收到的是ICMP数据包,继续向下执行;

———————————————————————————————————————

icmp_input:

此处为ICMP数据包处理部分,比较简单不做详解。

此部分仅仅接收ECHO命令,若接收到别的命令,则将数据包丢弃。若接收到的是ECHO命令则返回包含ECHO_REPLY的ICMP数据包给远方主机,主要是用来响应ping命令。

———————————————————————————————————————

udp_input:

根据要求校验UDP数据

在UDP连接列表中寻找接收到的数据包是否属于列表中的连接,若是则 goto udp_found;

如果不是则 goto drop;

udp_found:

接收到数据数设置uip_flags = UIP_NEWDATA; 将uip_sappdata,uip_appdata指向接收到的UDP包的数据部分。

调用UIP_UDP_APPCALL();使应用程序处理接收到的数据;

继续向下执行

udp_send:

如果uip_slen == 0表明没有数据要发送,则直接goto drop;

计算UDP数据包长度,填充UDP、IP帧头中的数据长度及相关选项;

根据要求计算校验和;

goto ip_send_nolen;发送UDP数据包;

———————————————————————————————————————

检查TCP校验和,若正确向下继续,若错误则丢弃此包直接返回;

在TCP连接列表uip_conns中轮询,检查接收到的TCP数据包是否已经建立连接(通过逐个比较源端口、目的端口和源IP是否与链接列表中的相同)。

若找到goto found;

没有找到则检查接收到的TCP数据包中是否含有SYN请求建立连接标志:

若没有则goto reset;发送RST+ACK断开连接;

若有则检查uip_listenports监听列表,若TCP数据包目的端口在监听列表中则goto found_listen;若不在监听列表中则向下执行,进入 reset;发送RST+ACK断开连接;

reset:

接收到的是RST断开连接包,则直接丢包,返回;

设置RST+ACK标志,填充适当的TCP帧头;

goto tcp_send_noconn;发送TCP数据包;

found_listen:

从链接列表中找出一个空链接或剩余生存时间最短的连接;

将找到的链接列表根据接收到的TCP数据包进行初始化;

设置TCP状态为UIP_SYN_RCVD;分析TCP的最大段长度;

向下执行,发送ACK

tcp_send_synack:

设置ACK标志

向下执行

tcp_send_syn:

设置SYN标志

填充TCP选项中最大报文段长度MSS

goto tcp_send;

found:

若接收到的是RST数据包,则将本连接状态置为UIP_CLOSED,uip_flags = UIP_ABORT;,调用UIP_APPCALL()通知应用程序处理连接断开请求。然后丢弃此包,直接返回;

检查接收到的数据包中的数据编号是否为自己等在等待的数据编号,若不是则goto tcp_send_ack;发送自己期望的数据编号的数据,即请求重传。若是则继续向下;

检查接收到的数据包中是否包含ACK,

若是则:

①更新发送数据序列的编号,使之可以发送后续数据;

②计算RTT时间,重新设置RTT时间;

③uip_flags = UIP_ACKDATA;表明接收到ACK

④uip_connr->len = 0;表明等待ACK的数据长度为0,即可以发送其它数据

⑤继续向下;

若不是:继续向下;

TCP状态机

switch(tcpstateflags)

case UIP_SYN_RCVD:

检查uip_flags==UIP_ACKDATA即是否接收到对自己发送SYN的ACK确认,

若是则:

①cpstateflags = UIP_ESTABLISHED;

uip_flags = UIP_CONNECTED;/*连接成功*

②检查数据包长度是否包含数据部分,若是则uip_flags |= UIP_NEWDATA;

③调用UIP_APPCALL()处理刚建立的连接和新接收到数据;

⑤goto appsend;

若不是则goto drop;丢包返回;

case UIP_SYN_SENT:

如果接收到ACK且为SYN+ACK则:

①检查TCP扩展选项,如果有扩展选项从中取出MSS信息;

②tcpstateflags = UIP_ESTABLISHED;进入ESTABLISHED状态

③设置接收编号,uip_flags = UIP_CONNECTED |UIP_NEWDATA;调用UIP_APPCALL()处理刚建立的连接和新接收到数据;

④goto appsend;

没有接收到ACK且为SYN+ACK则:

①uip_flags = UIP_ABORT;终止连接调用UIP_APPCALL();

②tcpstateflags = UIP_CLOSED;关闭TCP连接

③goto reset;

case UIP_ESTABLISHED:

接收到远方主机的FIN请求:

① uip_flags |= UIP_CLOSE;关闭TCP连接

②如果接收到的数据包中还包含有数据则uip_flags |= UIP_NEWDATA;

③调用UIP_APPCALL()处理刚关闭的连接和新接收到数据;

④发送TCP_FIN +TCP_ACK,关闭连接;

如果接收到的数据状态为UIP_NEWDATA | UIP_ACKDATA则:

①调用UIP_APPCALL();处理接收到的包;

appsend:

如果(uip_flags & UIP_ABORT)终止连接则

①tcpstateflags = UIP_CLOSED;关闭TCP连接;

②发送RST+ACK关闭连接;

如果(uip_flags & UIP_CLOSE)正常关闭连接则:

①tcpstateflags = UIP_FIN_WAIT_1;进入等待关闭状态

②发送FIN+ACK告知对方关闭连接;

如果uip_slen > 0有数据要发送则设置发送数据的长度

apprexmit:

如果(uip_slen > 0 && uip_connr->len > 0)则发送PSH_ACK数据包;

如果(uip_flags & UIP_NEWDATA)仅仅是发送ACK,没有数据要发送则发送对接收到数据的ACK;

以上都不是goto drop;

case UIP_LAST_ACK:

如果uip_flags & UIP_ACKDATA接收到对本机发送的FIN的ACK确认则:

①tcpstateflags = UIP_CLOSED;将连接置为关闭状态

②uip_flags = UIP_CLOSE;调用UIP_APPCALL();通知应用程序连接已经断开;

case UIP_FIN_WAIT_1:

此时本机已经关闭连接等待对方关闭连接,如果接收到数据并不处理,仅仅将接收到数据包数目加一;

如果接收到FIN请求:

①如果(uip_flags & UIP_ACKDATA)接收到对本机发送FIN的确认则将连接状态置为tcpstateflags=UIP_TIME_WAIT;

②否则的话则将连接状态置为tcpstateflags = UIP_CLOSING;

③uip_flags = UIP_CLOSE; 调用UIP_APPCALL();通知应用程序有一方已经关闭连接

④goto tcp_send_ack;

如果(uip_flags & UIP_ACKDATA)仅仅接收到ACK则设置连接状态标志tcpstateflags= UIP_FIN_WAIT_2; 进入等待对方关闭阶段

如果(uip_len > 0)表明接收到数据包则goto tcp_send_ack;发送对接收到数据的确认ACK;

goto drop;

case UIP_FIN_WAIT_2:

此时本机已经关闭连接等待对方关闭连接,如果接收到数据并不处理,仅仅将接收到数据包数目加一;

如果接收到对方发送的FIN请求。则

①设置tcpstateflags = UIP_TIME_WAIT;进入超时关闭状态;

②uip_flags = UIP_CLOSE; 调用UIP_APPCALL();通知应用程序有一方已经关闭连接

③goto tcp_send_ack;

如果(uip_len > 0)表明接收到数据包则goto tcp_send_ack;发送对接收到数据的确认ACK;

goto drop;

case UIP_TIME_WAIT:

(1)goto tcp_send_ack;

case UIP_CLOSING:

如果(uip_flags & UIP_ACKDATA)接收到对FIN的ACK,连接进入超时等待状态tcpstateflags=UIP_TIME_WAIT;

Endcase

———————————————————————————————————————

tcp_send_ack:

设置ACK标志

tcp_send_nodata:

将长度设为帧头长度,不包含数据

tcp_send_noopts:

将选项长度设为0

tcp_send:

填充TCP帧头确认编号和发送编号,IP地址和端口号;

如果tcpstateflags & UIP_STOPPED要求暂停发送数据则将接收窗口设为0;禁止对方往自己发送数据;

tcp_send_noconn:

设置TCP包生存时间,传送的数据的长度;

计算TCP校验和

ip_send_nolen:

设置IP帧头中的各个选项

计算IP校验和

send:

将发送的数据包计数器加一;

uip_flags = 0; return;

drop:

(1)uip_len = 0;

(2)uip_flags = 0;

(3)return;

uip tcp udp运行流程详解相关推荐

  1. 基于socket网络编程技术实现TCP和UDP的流程详解及实例

    具体函数讲解太多,根据程序自行分析. 可以参考这篇文章: https://blog.csdn.net/qq_41687938/article/details/119102328?spm=1001.20 ...

  2. [windows网络编程]tcp/udp编程初步详解-转

    #pragma comment (lib,"ws2_32.lib") #include <Winsock2.h> #include <stdio.h> 如你 ...

  3. python threading condition使用_Python threading模块condition原理及运行流程详解

    Condition的处理流程如下: 首先acquire一个条件变量,然后判断一些条件. 如果条件不满足则wait: 如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wa ...

  4. python执行过程_Python threading模块condition原理及运行流程详解

    Condition的处理流程如下: 首先acquire一个条件变量,然后判断一些条件. 如果条件不满足则wait: 如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wa ...

  5. TCP/IP五层模型详解

    TCP/IP五层模型详解 应用层 HTTP:简单的明文传输的请求--响应协议 HTTP数据结构: 首行 头部 空行 正文 浏览器的控制 HTTPS 定义 CA认证 SSL加密流程: 混合对称加密过程: ...

  6. 前端基础-TCP/IP 不完全详解

    TCP/IP 不完全详解 TCP/IP是通信协议的统称.首先,我们先认识一下OSI参考模型 OSI 参考模型 OSI 参考模型中各个分层的作用如下: 概括的说: 应用层:为应用程序提供服务并规定应用程 ...

  7. 【联机对战】微信小程序联机游戏开发流程详解

    现有一个微信小程序叫中国象棋项目,棋盘类的单机游戏看着有缺少了什么,现在给补上了,加个联机对战的功能,增加了可玩性,对新手来说,实现联机游戏还是有难度的,那要怎么实现的呢,接下来给大家讲一下. 考虑到 ...

  8. 负载均衡原理与实践详解 第五篇 负载均衡时数据包流程详解

    负载均衡原理与实践详解 第五篇 负载均衡时数据包流程详解 系列文章: 负载均衡详解第一篇:负载均衡的需求 负载均衡详解第二篇:服务器负载均衡的基本概念-网络基础 负载均衡详解第三篇:服务器负载均衡的基 ...

  9. Android事件流程详解

    Android事件流程详解 网络上有不少博客讲述了android的事件分发机制和处理流程机制,但是看过千遍,总还是觉得有些迷迷糊糊,因此特地抽出一天事件来亲测下,向像我一样的广大入门程序员详细讲述an ...

最新文章

  1. 取消Eclipse等号、分号、空格代码自动补全
  2. linux socket SO_KEEPALIVE选项
  3. linux如何修改权限详解
  4. React.js 小书 Lesson5 - React.js 基本环境安装
  5. 出现authentication mode=Windows/错误解决办法
  6. python sort 多级排序_sort、sorted排序技巧(多级排序)
  7. hdu 5167 Fibonacci(预处理)
  8. qtmessagebox对话框里自定义按钮文本_按钮你可以这样设计
  9. 喜笑等动作收集起来的扎金花GAME
  10. __proto__和prototype 1
  11. 网管师职业认证网上辅导班开课前的调查
  12. 3.3 Zend_Db_Table
  13. training test validation 各有其用,实践中有了体会
  14. 计算机环境变量win10,Win10系统path环境变量怎么设置
  15. JDK11竟然不支持字体斜体
  16. ajax submittype,AjaxSubmit()提交file文件
  17. 零基础入门机器学习——声音识别——打卡Task1
  18. 机智云开源框架二次开发之换皮肤,几乎不用改代码
  19. 计算机毕业设计基于Android的计算器app设计
  20. select 多选下拉框获取值

热门文章

  1. 文档,数据和粘贴板 目录 AppKit 文档
  2. JavaScript图片切换
  3. Java开发人员必须掌握的166个Linux命令
  4. [JetBrains注册] 利用教育邮箱注册JetBrains产品(pycharm、idea等)的方法
  5. web app 框架
  6. java 图片url转base64_JAVA 将base64图片存到本地,同时生成url(代码可以直接运行)...
  7. 锂电池正常分容测试温度的软件,电池化成分容测试系统
  8. java 给qq邮箱发邮件_java实现163邮箱发送邮件到qq邮箱成功案例
  9. 高端内存映射之kmap持久内核映射--Linux内存管理(二十)
  10. android安装命令行工具下载,Command line tools下载-Command line tools(命令行工具)下载 v1.0官方版--pc6下载站...