通信软件设计方法-第五讲-状态机程序设计与无状态协议程序设计_第1页
通信软件设计方法-第五讲-状态机程序设计与无状态协议程序设计_第2页
通信软件设计方法-第五讲-状态机程序设计与无状态协议程序设计_第3页
通信软件设计方法-第五讲-状态机程序设计与无状态协议程序设计_第4页
通信软件设计方法-第五讲-状态机程序设计与无状态协议程序设计_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、通信软件设计方法杨雄 编写,二零零九年四月,1,讲授内容,1)LINUX概况 2)LINUX下C语言程序编译和调试 2.1)LINUX开发环境学习(实验) 3)通信系统和通信软件 4)基于TCP-IP的主机到主机通信软件示例 4.1)SOCKET程序设计(实验) 5)有状态与无状态通信协议程序设计 6)LINUX内核程序设计 7)低层232接口通信程序设计 8)设计一个简单链路层以及程序 8.1)IP软件和链路层软件设计(实验),2,本讲重点问题,如何编写状态机程序,3,第五讲 有状态与无状态通信协议程序设计,协议与状态机 状态机程序设计 IP转发程序设计,4,协议与状态机,什么是协议?,5,

2、协议与状态机,标准规范协议 私有的协议,协议就是通信规程,通信双方或多方的信息传输约定 信息传输: 1、控制信息(数据);2、运载信息(数据) 通信系统的核心就是协议,6,协议与状态机,协议分为无状态协议与有状态协议,无状态协议:信息处理和历史记录无关 例如 IP,有状态协议:信息处理和历史记录有关 例如 TCP 有状态协议用状态机来表示 或者状态图来表示,7,协议与状态机,有限状态机的元素,状态 协议的一个逻辑概念,规定特定状态下可以接受特定 事件和执行相应动作 事件 PDU、时钟计数溢出、系统管理指令 动作 功能程序,8,协议与状态机,状态机简单例子,2个状态 4个事件 若干动作,状态S1

3、 Disconnected 断开,状态S2 Connected 连接,事件E4 关闭 (Shutdown) - 送关闭信息PDU给对方 关闭时钟,事件E1 本地初始化 (Initialization) - 送启动信息PDU给对方 开启时钟,事件E2 收到对方来的数据PDU (Protocol Message) - 处理接收的PDU,事件E3 时钟到 (Timer Expiry) - 定时处理,9,协议与状态机,如何编写这个状态机程序?,10,状态机程序设计 示例6,Switch-case结构方法,switch (event) case E1: /* Initialize */ If (curr

4、ent_state = DISCONNECTED) InitializeProtocol (); current_state = CONNECTED; break; case E2: /* Protocol Messages */ If (current_state = CONNECTED) ProcessMessages (); break; case E3: /* Timer Event(s) */ If (current_state = CONNECTED) ProcessTimers (); break; case E4: /* Disconnect Event */ If (curr

5、ent_state = CONNECTED) ShutdownProtocol (); current_state = DISCONNECTED; break; default: logError (Invalid Event, current_state, event); break; ,int event; int current_stat;,Event变量的数值从哪里获得?,增加case语句,再用switch-case结构,11,状态机程序设计,switch-case结构 + 主循环, while (1) get_event( ,获得事件,判断事件,根据状态情况处理事件,12,状态机程序

6、设计,数据结构方法,状态事件表 矩阵M*N,N表示状态数量,M表示事件数量 交叉点中-Action, Next State,M事件,N状态,13,状态机程序设计 示例7,数据结构方法-程序,/* 当前状态和事件的入口是SetEventCurrentState */ while (1) get_event( ,/* 入口矩阵是SetMN */ struct enter *Action(); int next_state; SetMN;,/* 函数参数 */ struct parameter PDU *pdup; Environment *ep; parameter;,14,状态机程序设计,数据结

7、构方法-表,15,协议与状态机,TCP的状态机是什么?,16,TCP的有限状态机,CLOSED,ESTABLISHED,LISTEN,CLOSE_WAIT,FIN_WAIT_1,SYN_RCVD,FIN_WAIT_2,CLOSING,TIME_WAIT,SYN_SENT,LAST_ACK,主动打开,被动打开,被动关闭,主动关闭,起点,被动打开,主动打开 发送 SYN,同时打开,收到 SYN,发送 SYN, ACK,收到 ACK,数据传送 阶段,关闭 发送 FIN,关闭 发送 FIN,关闭 发送 FIN,收到 RST,收到 SYN 发送 SYN, ACK,关闭 或超时,收到 ACK,收到 SYN

8、, ACK 发送 ACK,收到 ACK,收到 ACK,收到 FIN 发送 ACK,收到 FIN, ACK 发送 ACK,收到 FIN 发送 ACK,同时关闭,收到 FIN 发送 ACK,发送 SYN,定时经过两倍报文段寿命后,关闭,17,设置互斥,事件队列 为空?,恢复互斥,取出事件,事件分析和处理,睡眠等待,如事件队列空, 则从发送队列中 取队列头块 根据头块的标记 做TCP/IP包 并向IP层传递,事件分析和处理,WU2PIOC,WU2PD,WP2UWA,WI2PD,WP2IWA,WU2PCL,WTMO,执行高层的ioctl请求,处理高层传来的数据,修改连接接收窗口,接受IP数据包,修改向

9、IP发送数据窗口,接收高层关闭连接请求,超时处理,TCP进程主流程,比如打开连接,流控,18,本章重点问题,如何编写IP程序,19,第五讲 有状态与无状态通信协议程序设计,IP的功能是什么?,20,通信网络系统,21,通信网络系统,数据包交换,以太网络,点到点网络,22,网络接口,缓冲区 数据队列,转发表 (路由表),IP接收和转发,接收 缓冲区,接收 缓冲区,接收 缓冲区,接收 缓冲区,接收 缓冲区,每个网络 接口设计 一个队列,核外 进程 部分,接口中断处理子程序,接收 缓冲区,其他 任务,IP数据报文队列,第五讲 有状态与无状态通信协议程序设计,23,第五讲 有状态与无状态通信协议程序设

10、计,IP的软件包有那些模块?,24,数据包 处理 模块,添加首部 模块,重装模块,路由寻找模块,分片模块,IP分组,IP分组,IP分组,TCP/IP分组,TCP/IP分组,目的地址,IP分组 下一跳 接口,IP分组,下一跳,IP分组,重装表,路由表,MTU表,IP软件包,ARP以及数据链路层,TCP层,接口号,目的地址,分片标记等,25,第五讲 有状态与无状态通信协议程序设计,IP主程序,while (1) 判断输入队列有IP报文吗? 如没有,则睡眠 从输入队列中取一个IP报文 调用数据包报文处理模块 根据处理结果 出错,抛弃改报文,结束本次循环 本机报文,调用重装模块 转发报文,调用路由寻找

11、模块 如存在路由,则调用下层模块 ,26,数据包 处理 模块,添加首部 模块,IP分组,IP分组,TCP/IP分组,目的地址,处理模块(参数是需要处理的IP报文) 1、检查数据报文 1)版本合法 2)长度合法 3)检验和正确 4)以上之一是NO,出错返回 2、若目的地址是127.x.x.x或是本地IP地址 A)本机返回 3、若是路由器 A)TTL减1,如TTL为0则出错返回 4、转发返回,TCP层,ARP以及数据链路层,27,路由寻找模块,IP分组,TCP/IP分组,IP分组 下一跳 接口,IP分组,下一跳,路由表,IP软件包,ARP以及数据链路层,TCP层,目的地址,28,IP路由表,Q,S

12、,10.0.0.5,20.0.0.5,30.0.0.6,40.0.0.7,30.0.0.7,20.0.0.6,R,40.0.0.0,30.0.0.0,20.0.0.0,10.0.0.0,路由器R的路由表,要到达的网络,下一个路由器/下一跳,20.0.0.5,30.0.0.5,10.0.0.5,40.0.0.5,直接,30.0.0.7,20.0.0.5,直接,第五讲 有状态与无状态通信协议程序设计,29,IP路由交换,路由选择的次序为: 直接交付 特定主机路由选择 特定网络路由选择 默认路由选择,第五讲 有状态与无状态通信协议程序设计,30,IP路由交换,从数据报中提取目的IP地址D; A)对路

13、由表中的每一个项目I ,并计算网络前缀N A)若N与I的网络的地址匹配(和目的地址比较) 1)如是网关(G出现) 使用路由表中的下一跳项目作为下一跳地址(间接交付) 2)如不是网关(G不出现) 使用分组的目的地址作为下一跳地址(直接交付) 3)把分组连同下一跳地址传送到分片模块 4)停止 B)找不到匹配,则发送给报文源ICMP差错报文 C)停止,第五讲 有状态与无状态通信协议程序设计,31,路由寻找模块,IP分组,TCP/IP分组,IP分组 下一跳 接口,IP分组,下一跳,路由表,IP软件包,ARP以及数据链路层,TCP层,目的地址,路由寻找模块 1、取得数据报文中目的地址D 2、从头到尾循环

14、检查路由表当前i 1)求出D的网络地址N 2)比较N和路由表的i.目的地址 3)如匹配转4 3、如查找完成,但尚未存在匹配则 1)出错返回 4、从路由表i中取得出口号码 5、存在路由返回,32,第五讲 有状态与无状态通信协议程序设计,IP软件的关键数据结构 是哪几个?,33,IP数据包格式,第五讲 有状态与无状态通信协议程序设计,34,typedef unsigned char u_int8_t;/8位 typedef unsigned short u_short; /16位 struct ip_addr unsigned long IP_addr; /IP地址,占32位 ; struct i

15、p_mask unsigned long IP_mask; /IP掩码,占32位 ;,第五讲 有状态与无状态通信协议程序设计,示例程序8,35,struct ip_hdr unsigned short intIP_v:4; / 版本号码 unsigned short intIP_hl:4; / 首部长度 u_int8_tIP_tos; / 服务类型 u_shortIP_len; / 数据报文总长度 u_shortIP_id;/ 标识 u_short IP_off; / 分段偏移 u_int8_tIP_ttl; / 存活时间 u_int8_tIP_p; / 协议号码 u_shortIP_sum;

16、 / 检验和 struct ip_addrIP_src,IP_dst; / 源IP地址和目的IP地址 ;,第五讲 有状态与无状态通信协议程序设计,36,固定长度的IP数据报文 #define IP_DATA1024 struct ip_data struct ip_hdr IP_hdr; charIP_dataIP_DATA; ;,第五讲 有状态与无状态通信协议程序设计,37,第五讲 有状态与无状态通信协议程序设计,输入队列: #define INPUT_QUEUE 100 struct ip_data IP_InputQueueINPUT_QUEUE; int IP_InputQueue_h

17、ead, IP_InputQueue_tail; 输出到低层队列: /有低层定义,IP传输IP报文给低层模块/程序即可 输出到高层队列: #define OUTPUT_QUEUE_TRAN 10 struct ip_data IP_OutQueueToTranOUTPUT_QUEUE_TRAN; int IP_OutQueueToTran_head, IP_OutQueueToTran_tail;,38,IP路由表,4byte4byte4byte 1byte 1int 1long 1int,第五讲 有状态与无状态通信协议程序设计,39,IP路由表数据类型,struct routing_tabl

18、e struct ip_mask RT_mask; struct ip_addr RT_IP_address; struct ip_addr RT_IP_next; char RT_flag; int RT_datagram_count; long RT_user_conut; int RT_interface; ,掩码 - 4byte 目的地址 - 4byte 下一跳地址 - 4byte 标记 - 1byte 引用记数 - 1int 使用记数 - 1long 接口号码 - 1int,第五讲 有状态与无状态通信协议程序设计,40,IP路由表变量数组,#define ROUTING_TABLE_

19、MAX_NUMBER 10 struct routing_table RoutingTableROUTING_TABLE_MAX_NUMBER;,第五讲 有状态与无状态通信协议程序设计,41,第五讲 有状态与无状态通信协议程序设计,IP软件的关键函数 是哪几个?,42,第五讲 有状态与无状态通信协议程序设计,处理模块(参数是需要处理的IP报文) 1、检查数据报文 1)版本合法 2)长度合法 3)检验和正确 4)以上之一是NO,出错返回 2、若目的地址是127.x.x.x或是本地IP地址 A)本机返回 3、若是路由器 A)TTL减1,如TTL为0则出错返回 4、转发返回,CheckIpData

20、(IP报文指针) 返回值: 1,合法 -1,版本错误 -2,长度错误 -3,检验和不正确,IsThisMachine (IP报文指针) 返回值: 1,转发 2,本机接收 -1,错误 本机地址变量:ThisIPAddress,路由器标记变量IsRouter 值:1是路由器,0是主机,43,路由寻找模块 1、取得数据报文中目的地址D 2、从头到尾循环检查路由表当前i 1)求出D的网络地址N 2)比较N和路由表的i.目的地址 3)如匹配转5 3、如查找完成,但尚未存在匹配则 1)出错返回 4、从路由表i中取得出口号码 5、存在路由返回,Analyze(struct ip_addr *NetP, st

21、ruct ip_addr *DestP) 返回值: 0,不匹配 1,匹配,第五讲 有状态与无状态通信协议程序设计,44,第五讲 有状态与无状态通信协议程序设计,IP软件包的模块程序怎么写?,45,第五讲 有状态与无状态通信协议程序设计,IpDataProcess(struct ip_data *IpDataP) int CheckR; CheckR = CheckIpData(IpDataP); switch (CheckR) case VER_INVALID: case LENTH_INVALID: case CHECK_SUM_FAILING: if (IsThisMachine(IpDa

22、taP-IP_Dst) return THIS_MACHINE; if (IsRouter) int ttl = -IpDataP-IP_ttl; if (ttl = 0) rerurn PROCESS_IPDATA_TTL; CheckSum(IpDataP); return FORWARD; ,处理模块(参数是需要处理的IP报文) 1、检查数据报文 1)版本合法 2)长度合法 3)检验和正确 4)以上之一是NO,出错返回 2、若目的地址是127.x.x.x或是本地IP地址 A)本机返回 3、若是路由器 A)TTL减1,如TTL为0则出错返回 4、转发返回,46,第五讲 有状态与无状态通信协

23、议程序设计,IpDataProcess(struct ip_data *IpDataP) int CheckR; CheckR = CheckIpData(IpDataP); switch (CheckR) case VER_INVALID: ret = PROCESS_IPDATA_VER; goto leave; case LENTH_INVALID: ret = PROCESS_IPDATA_LENTH; goto leave; case CHECK_SUM_FAILING: ret = PROCESS_IPDATA_CHECK_SUM; goto leave; if (IsThisMa

24、chine(IpDataP-IP_Dst) return THIS_MACHINE;,if (IsRouter) int ttl = -IpDataP-IP_ttl; if (ttl = 0) rer = PROCESS_IPDATA_TTL; goto leave; CheckSum(IpDataP); ret = PROCESS_IPDATA_OK; Leave: return ret ,47,IsForwardOrdiscard (struct ip_data *IpDataP, int *IfNoP); int RoutingTableIndex; struct ip_addr Des

25、t; bcopy( ,路由寻找模块 1、取得数据报文中目的地址D 2、从头到尾循环检查路由表当前i 1)求出网络地址N 2)比较N和路由表的i.目的地址 3)如匹配转5 3、如查找完成,但尚未存在匹配则 1)出错返回 4、从路由表i中取得出口号码 5、存在路由返回,48,IsForwardOrdiscard (struct ip_data *IpDataP, int *IfNoP); int RoutingTableIndex; struct ip_addr Dest; bcopy( ,第五讲 有状态与无状态通信协议程序设计,49,IsThisMachine(struct ip_addr *D

26、estP) if (*DestP = 127) return 1; return Analyze( ,第五讲 有状态与无状态通信协议程序设计,50,Resolve(struct ip_mask *MaskP, struct ip_addr *DestP, struct ip_addr *NetP) int i; char *d = (char *) DestP; char *m = (char *) MaskP; char *n = (char *) NetP for (i = 0; i siezof *DestP; i+) *n+ = (*d+) ,第五讲 有状态与无状态通信协议程序设计,5

27、1,第五讲 有状态与无状态通信协议程序设计,IP软件包中队列操作如何写?,52,第五讲 有状态与无状态通信协议程序设计,队列首下标,队列尾下标,取IP数据报文不释放空间 返回队列首下标的地址,放IP数据报文 把数据报文拷贝到队列下标指示的地址空间中; 队列下标+;if (队列下标到最大值)队列下标 = 0;,释放空间 队列首下标+; if (下标到最大值) 队列下标 = 0;,53,第五讲 有状态与无状态通信协议程序设计,输入队列: #define INPUT_QUEUE 100 struct ip_data IP_InputQueueINPUT_QUEUE; int IP_InputQueu

28、e_head, IP_InputQueue_tail; 输出到低层队列: /低层定义 输出到高层队列: #define OUTPUT_QUEUE_TRAN 10 struct ip_data IP_OutQueueToTranOUTPUT_QUEUE_TRAN; int IP_OutQueueToTran_head, IP_OutQueueToTran_tail;,54,第五讲 有状态与无状态通信协议程序设计,输入队列: #define INPUT_QUEUE 100 struct ip_data IP_InputQueueINPUT_QUEUE; int IP_InputQueue_head

29、, IP_InputQueue_tail; 从输入队列释放一个IP数据报文空间操作 ReleaseIP_InputQueue() IP_InputQueue_head+; if (IP_InputQueue_head = INPUT_QUEUE) IP_InputQueue_head = 0; ,55,第五讲 有状态与无状态通信协议程序设计,输入队列: #define INPUT_QUEUE 100 struct ip_data IP_InputQueueINPUT_QUEUE; int IP_InputQueue_head, IP_InputQueue_tail; 从输入队列取一个IP数据报

30、文操作不释放,不拷贝 struct ip_data *GetIPDataFromInputQueue() return ,56,第五讲 有状态与无状态通信协议程序设计,输入队列: #define INPUT_QUEUE 100 struct ip_data IP_InputQueueINPUT_QUEUE; int IP_InputQueue_head, IP_InputQueue_tail; 放IP数据报文到输入队列操作保证有空间! PutIPDataToIP_InputQueue(struct ip_data *IPDataP) reigster int index = IP_InputQueue_tail; bcopy(IPDataP, IP_InputQueueindex, sizeof *IPData); if (+index = INPUT_QUEUE) index = 0; IP_InputQueue_tail = index; ,57,第五讲 有状态与无状态通信协议程序设计,输出队列到高层: #

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论