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. SpringBoot巧用 @Async 提升API接口并发能力!
  2. 手机端自适应字体大小和元素宽度自适应
  3. 网络爬虫:基于对象持久化实现爬虫现场快速还原
  4. JavaScript实现hamiltonianCycle哈密尔顿图算法(附完整源码)
  5. 【tensorflow-keras-GRU】keras.layers.GRU 门限循环单元网络(Gated Recurrent Unit)
  6. 【爬虫】爬取百度贴吧数据
  7. 1-4-14:计算邮资
  8. php实现数值的整数次方
  9. Java:注解和反射
  10. linux ntfs 密码,linux 加载ntfs和fat32分区
  11. kill apache
  12. centos mysql5.6.35_centos6.8 mysql 5.6.35 glibc安装
  13. redis desktop manager 集群_Redis Manager(2.0) —— Redis 运维利器
  14. [译] 你的站点如你所想的移动友好吗?
  15. Oracle 创建表语句
  16. java中怎么读取txt文件_Java读取TXT文件
  17. docker图形化监控容器资源使用情况【cadvisor和scope】
  18. 《加密与解密》笔记五(二)
  19. 黑白图转RGB(Matlab)
  20. element-ui实现表格分页和搜索功能

热门文章

  1. 利用Openfiler配置基于文件系统的网络存储
  2. 我的PMP学习考试心得
  3. win10卸载程序灾难性故障_这款Win10系统维护神器,专业强大独具特色,是优化系统的好帮手...
  4. Android驾驶证拍照识别技术
  5. nginx5种负载策略的设置方法
  6. 2.2云计算架构概述
  7. realvnc viewer安卓下载,realvnc viewer安卓下载工具加使用方法
  8. [欠驱动机器人]3,Acobot,Cart-pole和Quadrotors
  9. 033 | JAVA班主任管理系统(源代码+论文) | 大学生毕业设计 | 极致技术工厂
  10. python requests 上传文件_Fastapi 上传多个文件(包含服务器端和python客户端代码)...