C++基于局域网Linux环境下的心跳检测系统实现.doc_第1页
C++基于局域网Linux环境下的心跳检测系统实现.doc_第2页
C++基于局域网Linux环境下的心跳检测系统实现.doc_第3页
C++基于局域网Linux环境下的心跳检测系统实现.doc_第4页
C++基于局域网Linux环境下的心跳检测系统实现.doc_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

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

文档简介

编 号: 审定成绩: 重庆邮电大学毕业设计(论文)设计(论文)题目:c+基于局域网linux环境下的心跳检测系统实现学 院 名 称 :计算机科学与技术学院学 生 姓 名 :胡 凯专 业 :计算机科学与技术专业班 级 :0490601学 号 :06100107指 导 教 师 :易 芝答辩组 负责人 :填表时间: 2010 年 6 月重庆邮电大学教务处-58-摘 要当今世界的网络飞速发展,但也因此也产生了许多网络故障,心跳检测技术作为一种故障检测技术,在当今服务器市场有很大需求。心跳检测技术是一种检测网络连接故障的技术,它通过在服务器端和客户端装上各自的心跳检测软件,就可以根据发送的心跳报文来监测故障,判断各个网络节点的连接是否正常1。 本文研究了心跳检测技术在linux平台下的实现,设计了一款能在局域网上运行的心跳检测系统。该系统采用tcp/udp协议,以c/s模式进行开发。服务器充当主控节点,客户端充当外围节点,通过客户端发送心跳报文的方法来实现心跳检测。系统在节点的局域网中使用,能达到很高的成功率。【关键词】心跳检测 主控节点 外围节点 报文 linuxabstractnetwork technology of todays world has the rapid development ,but also produces so many network failure, heartbeat detection technology is a detection technology as a network failure detection , and has much demand in todays server market.heartbeat detection technology is a network connection failure detection technology, server and client need only install on each heartbeat detection software, you can send packets to monitor heart failure, determine whether the various network nodes is in the normal .in this paper, the heartbeat detection technology implementation in the linux platform, designed a run in lan heartbeat detection system. the system uses tcp / udp protocol, to c / s model for development. server acts as the master node, the client acts as the external nodes, through the heartbeat messages sent by the client to achieve the heartbeat detection methods. system used in local area network node can achieve a high success rate.【key words】heartbeat detection master node peripheral node message linux目 录abstract2前 言4第一章 系统简介6第一节 心跳检测机制6第二节 本文设计的心跳检测系统6第三节 本章小结7第二章开发环境、工具和技术8第一节linux的介绍8第二节gcc简介9一、什么是gcc9二、gcc的基本规则10三、gcc的基本用法10四、执行过程11第三节 linux下的网络编程技术11一、socket编程介绍11二、tcp/udp开发简介16第四节 本章小结17第三章 系统的分析与设计18第一节 需求分析18一、问题定义18二、可行性研究18三、用户需求18四、系统整体用例图19第二节 概要设计19一、设计指导思想20二、心跳检测系统的整体结构图20三、总体设计21第三节详细设计22一、心跳表注册表的设计22二、报文格式的设计24三、外围节点的设计26四、主控节点的设计27第四节 本章小结31第四章 心跳检测系统的实现32第一节 linux下开发环境32一、编译环境32二、运行环境33第二节 程序的实现35一、外围节点的实现35二、主控节点的设计37第三节 本章小节40第五章 系统测试41第一节 测试环境41第二节 测试方法41一、黑盒测试42二、测试步骤42第三节 本章小结48结 论49参考文献51附 录52一、英文原文52二、中文翻译56前 言网络是一个庞大复杂的系统,有成千上万台设备节点,经常会出现连接故障,我们不可能用人力去监测,这时负责监测网络故障的心跳检测软件由此产生。心跳检测系统是基于c/s架构开发的网络检测系统,随着网络技术的发展而发展,在当今服务器市场上有很大需求,也日趋成熟化。比如linux平台下的heartbeat集群软件包就是成功的典型。我相信,在当今it技术的推动下,心跳检测在未来几年会有更广阔的发展空间。在了解了心跳检测的基本原理和linux网络编程的基本方法之后,我设计了一个可以在局域网上进行网络连接检测的心跳检测系统。并对里面涉及的技术原理,设计思想进行了相关讨论。第一章 系统简介第一节 心跳检测机制在分布式系统中,有成千上万个设备节点通过有线或者无线网络连接。这些节点和网络随时可能发生故障,从而导致部分节点或者网络瘫痪。为了确保整个系统正常工作,主控节点应该能随时知道其他节点当前是否在正常工作。如果用人力去监控,则会造成很大的开销,且节点是否瘫痪有时无法从外表判断。心跳检测系统可以节省人力,根据外围节点定期发送的报文来判断设备和网络是否发生故障。心跳检测技术是分布式嵌入式系统中一种常见的故障检测方法。在心跳检测中,外围节点将周期性向主控节点发送心跳报文。如果过一段时间之后,主控节点没有收到外围节点的心跳报文,则认为此节点或相关网络出现故障,并向管理员报告。它有如下特点:基于c/s模式,主控节点(服务器端)判断外围节点(客户端)是否正常运行,一般采用定时发送简单的心跳报文,如果在指定时间段内未收到对方响应,则判断连接出现故障。用于检测网络的异常断开。发包方可以是客户端也可以是服务器端,看哪边实现方便合理。一般是客户端,服务器也可以定时轮询发心跳下去(我的系统是采用客户端发报文)。检测方法就是外围节点每隔几分钟发送一个心跳报文给主控节点,服务端收到后回复一个响应报文。如果服务端在规定时间内没有收到客户端信息则视连接断开。第二节 本文设计的心跳检测系统在介绍了心跳检测系统的概念、特点、作用之后,下面介绍了我所设计的系统的一些情况。由于该设计主要是针对10台左右的小范围的局域网设计的心跳检测系统,没有涉及到数据库存储的相关知识,因此该系统的优点是所需要的硬件代价小,实现起来的网络连接相对简单,能针对自己组建的局域网来测试。当然,该设计的功能差了很多,比如在数据库中记录节点出错时间,监控节点数量的多少,网络阻塞引起的延时等方面并没有涉及到。我相信,我今后在学习更多网络故障检测技术和网络编程技术后,会将上述功能一一实现。 我的设计在linux平台下,采用了c/s模式,服务器端充当主控节点,客户端充当外围节点,外围节点先发送tcp报文进行和主控节点建立连接,在建立连接成功后,发送心跳报文,心跳报文则采用udp格式设计。而后每隔一秒发送一次心跳报文,主控节点根据心跳报文来检测网络连接是否正常。第三节 本章小结本章先从心跳检测的用途出发,介绍了心跳检测的概念,以及它使用的原理,使大家对心跳检测有了大致的了解。最后大致介绍了我自己设计的心跳检测系统的一些情况,包括优缺点和大致的实现情况。第二章 开发环境、工具和技术第一节 linux的介绍linux是一类unix计算机操作系统的统称。linux操作系统的内核的名字也是“linux”。linux操作系统也是自由软件和开放源代码发展中最著名的例子。严格来讲,linux这个词本身只表示linux内核,但在实际上人们已经习惯了用linux来形容整个基于linux内核,并且使用gnu 工程各种工具和数据库的操作系统。linux得名于计算机业余爱好者linus torvalds。当时他是芬兰赫尔辛基大学的学生。他的目的是想设计一个代替minix(是由一位名叫andrew tannebaum的计算机教授编写的一个操作系统示教程序)的操作系统,这个操作系统可用于386、486或奔腾处理器的个人计算机上,并且具有unix操作系统的全部功能,因而开始了linux雏形的设计。出于爱好,他根据可在低档机上使用的minix设计了一个系统核心linux 0.01,但没有使用任何minix或unix的源代码。他通过usenet(就是新闻组)宣布这是一个免费的系统,主要在x86电脑上使用,希望大家一起来将它完善,并将源代码放到了芬兰的ftp站点上任人免费下载。linux以它的灵活性和高效性著称。能够在个人计算机上面实现全部的unix的特性。具有多任务、多用户的能力。linux在gnu的gpl公共许可权下免费获得。linux不仅仅包括完整的操作系统,还包括文本编辑器、高级语言编译器等应用软件。它还包括带有多个窗口管理器的x-windows图形用户界面。目前,linux能够运用于各种版本的cpu的计算机上,还能运用于一些手持设备,比如说,pda,游戏机,手机,嵌入式产品等等。由于linux的开源性以及免费性,很多厂家都选择应用linux开发,以降低成本,在增强竞争力的同时也推进了linux系统的发展。 绝大多数基于linux内核的操作系统使用了大量的gnu软件,包括了shell程序、工具、程序库、编译器及工具,还有许多其他程序,例如emacs。linux的基本思想有两点:第一,一切都是文件;第二,每个软件都有确定的用途。其中第一条详细来讲就是系统中的所有都归结为一个文件,包括命令、硬件和软件设备、操作系统、进程等等对于操作系统内核而言,都被视为拥有各自特性或类型的文件。至于说linux是基于unix的,很大程度上也是因为这两者的基本思想十分相近。linux的优点集中体现在以下几点:低廉性:基于其低廉成本与高度可设定性,linux常常被应用于嵌入式系统,例如机顶盒、移动电话及行动装置等。在移动电话上,linux已经成为与symbian os、windows mobile系统并列的三大智能手机操作系统之一;而在移动装置上,则成为windows ce与palm os外之另一个选择。广泛性:基于linux的开源性给人们带来的巨大诱惑,linux的的应用越来越广,linux社区的人员的增多,致使基于linux的开发越来越方便容易。根据2005年11月号的top500超级电脑列表,显示世上最快速的两组超级电脑都是使用linux作为其操作系统。而在表列的500套系统里,采用linux为操作系统的,占了371组(即74.2%),其中的前十位者,有7组是使用linux的。目前,除了一部分专家之外,大多数人都不自己选择每一样组件或自行设置,而是直接使用linux套件。灵活性:linux以它的高效性和灵活性著称。它能够在pc计算机上实现全部的unix特性,具有多任务、多用户的能力。linux是在gnu公共许可权限下免费获得的,是一个符合posix标准的操作系统。linux操作系统软件包不仅包括完整的linux操作系统,而且还包括了文本编辑器、高级语言编译器等应用软件。它还包括带有多个窗口管理器的x-window图形用户界面,如同我们使用windows nt一样,允许我们使用窗口、图标和菜单对系统进行操作。总的来说,linux由于有着诸多windows操作系统所缺乏的优点,能够让我们在嵌入式应用中如鱼得水2。第二节 gcc简介一、 什么是gccgcc是gnu公社的一个项目。是一个用于编程开发的自由编译器。最初,gcc只是一个c语言编译器,它是gnu c compiler 的英文缩写。随着众多自由开发者的加入和gcc自身的发展,如今的gcc已经是一个包含众多语言的编译器了。其中包括 c,c+,ada,object c和java等。所以,gcc也由原来的gnu c compiler变为gnu compiler collection。也就是 gnu编译器家族的意思。当然,如今的gcc借助于它的特性,可以交叉编译,即在一个平台下编译另一个平台的代码。直到现在,gcc的历史仍然在继续,它的传奇仍然被人所传颂。而且更重要的是gcc完全是一款免费的自由软件,加之其强大的功能所以深受广大用户的喜爱。二、gcc的基本规则gcc所遵循的部分约定规则: .c为后缀的文件,c语言源代码文件; .a为后缀的文件,是由目标文件构成的档案库文件; .c,.cc或.cxx 为后缀的文件,是c+源代码文件; .h为后缀的文件,是程序所包含的头文件; .i 为后缀的文件,是已经预处理过的c源代码文件; .ii为后缀的文件,是已经预处理过的c+源代码文件; .m为后缀的文件,是objective-c源代码文件; .o为后缀的文件,是编译后的目标文件; .s为后缀的文件,是汇编语言源代码文件; .s为后缀的文件,是经过预编译的汇编语言源代码文件。三、gcc的基本用法在使用gcc编译器的时候,我们必须给出一系列必要的调用参数和文件名称。gcc编译器的调用参数大约有100多个,其中多数参数我们可能根本就用不到,这里只介绍其中最基本、最常用的参数。 gcc最基本的用法是gcc options filenames 其中options就是编译器所需要的参数,filenames给出相关的文件名称。 -c,只编译,不连接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。 -o output_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。 -g,产生符号调试工具(gnu的gdb)所必要的符号资讯,要想对源代码进行调试,我们就必须加入这个选项。 -o,对程序进行优化编译、连接,采用这个选项,整个源代码会在编译、连接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、连接的速度就相应地要慢一些。 -o2,比-o更好的优化编译、连接,当然整个编译、连接过程会更慢。 -idirname,将dirname所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数。c程序中的头文件包含两种情况 a)#include b)#include “myinc.h” 其中,a类使用尖括号(),b类使用双引号(“ ”)。对于a类,预处理程序cpp在系统预设包含文件目录(如/usr/include)中搜寻相应的文件,而b类,预处理程序在目标文件的文件夹内搜索相应文件。四、执行过程 虽然我们称gcc是c语言的编译器,但使用gcc由c语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤:预编译,编译,汇编和链接 命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。接着调用cc1进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.s为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的档案库中连到合适的地方3。第三节 linux下的网络编程技术一、socket编程介绍在介绍心跳检测的详细设计之前,首先介绍linux下的网络程序设计方法。在linux系统中,最常用的网络应用编程结构是unix bsd的套接字接口。socket编程有字节流和数据报两种主要类型,分别对应tcp协议和udp协议。其中字节流socket定义了一种可靠的面向连接的服务,实现了无差错无重复的顺序数据传输。数据报socket定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且无法保证可靠无差错。无连接服务器一般都是面向事务处理的,一个请求一个应答就完成了客户和服务器之间的交互。下面就是本系统所用到的socket编程函数: 创建套接字:int socket( int domain, int type, int protocol ); 应用程序调用socket函数来创建一个能够进行网络通信的套接字。domain:指定应用程序使用的通信协议的协议族,对于tcp/ip协议族,该参数置af_inet;type:指定要创建的套接字类型,流套接字类型为sock_stream、数据报套接字类型为sock_dgram;protocol:指定应用程序所使用的通信协议,一般设置为0。该函数如果调用成功就返回新创建的套接字的描述符,套接字描述符是一个整数类型的值;如果失败就返回-1。 绑定套接字#includeint bind(int socket, const struct sockaddr *address, size_t address_len);socket:由socket()调用返回的套接字描述符;addreess:结构指针指向了与协议名称和协议相关的信息;address_len:指明了address数据结构的大小。如果调用成功,bind()函数返回0;否则返回-1,并设置错误代码到errno。 等待客户端连接服务器端应用软件通过调用accept()函数将自身阻塞,直至有新的客户端连接。#includeint accept(int socket,struct sockaddr *address,socketlen_t address_len);socket:创建并绑定的套接字;address:返回连接服务器的客户端地址信息;address_len:指明了address数据结构的大小。如果调用成功,则返回非负的连接套接字;否则返回-1,并设置错误代码到errno。 连接服务器客户端通过connect()函数和服务器进行tcp连接。#include int connect(int socket, const struct sockaddr *address, size_t address_len);socket:创建并绑定套接字;address:指明要连接服务器的ip地址和端口号;address_len:指明了address数据结构的大小。如果调用成功,返回0;否则返回-1,并设置错误代码到errno。 udp协议的发送数据udp协议需要通过sendto()函数实现一个数据包的发送,这是因为udp协议提供的是以数据包为单位的传输,而tcp协议提供的是以字节流为单位的传输。#includessize_t sendto(int socket,const void*message,size_t length,int flags,const struct sockaddr*dest_addr,socklen_t dest_len);socket:已经创建的套接字;message:指明要发送的数据包的地址;length:数据包大小;flags:设置发送的属性,一般可设置为0;dest_addr:指明目的端的ip地址和端口号;dest_len:指明dest_addr数据结构的大小。如果调用成功,返回实际发送的数据数目;否则返回-1,并设置错误代码到errno。 udp协议的接收数据udp协议需要通过recvfrom()函数接收一个数据包。#includessize_t recvfrom(int socket,void* buffer,size_t length,int flags,struct sockaddr* address,socklen_t address_len);socket:已经创建的套接字;message:指明要接收的数据包的地址;length:数据包大小;flags:设置发送的属性,一般可设置为0;dest_addr:指明目的端的ip地址和端口号;dest_len:指明dest_addr数据结构的大小。如果调用成功,返回实际发送的数据数目;否则返回-1,并设置错误代码到errno。 向一个已连接的套接口发送数据。#include ssize_t send(int socket, const char void* buffer, int length, int flags);socket:一个用于标识已连接套接口的描述字;buffer:包含待发送数据的缓冲区;length:缓冲区中数据的长度;flags:调用执行方式;若无错误发生,send()返回所发送数据的总数;否则的话,返回-1并把错误保存到errno。 从一个已连接的套接口接收数据。#include ssize_t recv( int socket, char * buffer, int length, int flags);socket:一个标识已连接套接口的描述字;buffer:用于接收数据的缓冲区;length:缓冲区长度;flags:指定调用方式;若无错误发生,recv()返回读入的字节数。如果连接已中止,返回0;否则的话,返回-1并把错误保存到errno。 ip地址的转换和获取在上述套接字程序设计中,服务器和客户端的ipv4地址采用了32为无符号整数表示。在用户方面,广泛使用的是十进制字符串表示(例如2)或者主机名称(例如)。linux操作系统提供了一系列函数实现这几种格式之间的转换。#includein_addr_t inet_addr(char* cp);cp:指向十进制字符串表示的ipv4地址。如果调用成功,返回ipv4地址的32位无符号整数表示;否则返回in_addr_t-l。 gethostbyname()函数可以实现从主机名称到32位无符号整数表示的转换。#includestruct hostent char *h_name; char *h_aliases; int h_addrtype; int h_length; char *h_addr_list;struct hostent *gethostbyname(const char *name);name:指明了主机名称的字符串。如果调用成功,返回指向hostent的指针;否则返回null,并设置错误代码到h_erno。其中hostent中的h_length指明了主机地址的长度,在ipv4协议下始终为1。h_addr_list指明了主机的所有网络地址。一般情况下,h_addr_list0就表明了此主机ipv4地址的32位无符号整数表示。 gethostbyaddr()函数可以实现从32为无符号整数到主机名称的转换。#includestruct hostent *gethostbyaddr(const void *addr,socklen_t len,int type);addr:指明了32位无符号整数表示的ipv4地址;len:指明了地址长度;type:在ipv4协议下,可以设置为af_inet。如果调用成功,返回指向hostent的指针;否则返回null,并设置错误代码到h_errno。 线程创建函数#includeint pthread_create(pthread_t *thread,pthread_ayyr_t *attr,void*(*start_routine)(void *),void *arg)thread:这是一个指向pthread_t类型数据的指针。线程被创建时,这个指针指向的变量中将被写入一个标识符,我们用该标识符来引用线程。attr:这个参数一般用于设置线程的属性,我们一般不需要设置特殊的属性,所以可以简单的设置该参数为null。start_routine :这个参数告诉线程将要启动的函数。arg:这个参数将传递启动函数的参数 。二、tcp/udp开发简介1、tcp开发介绍在基于tcp协议的程序设计中一般采用客户端/服务器的程序设计模式。在服务器端首先使用socket()函数创建套接字,然后使用bind()函数将本机ip地址和服务端口绑定至套接字,并通过listen()函数建立等待队列,随后就可以使用accept()函数等待客户端的连接。accept()函数将一直阻塞,直至有一个客户端连接到本地服务器端口为止。该函数将返回一个新的套接字值,随后服务器就可以通过新的套接字接口与连接上的客户端利用rend()或write()函数进行交互。客户端在访问服务器时首先要通过socket()函数调用,然后通过connect()函数连接服务器的ip地址和相应的服务器端口号。连接成功后,就可以通过read()或者write()函数与服务器进行数据交互了。客户端/服务器结构下的tcp应用程序框架如图所示5:socket():创建套接字bind():绑定本机地址和端口号listen():设置等待队列accept():等待客户端连接sendto()和recv()与客户端交换数据close()关闭特定客户端套接字socket:创建套接字connect()连接服务器sendto()和recv()与服务器端交换数据close()关闭套接字建立请求图2.1客户端/服务器结构下的tcp协议程序结构图2、udp开发介绍基于udp协议的应用程序设计比较简单。首先通信双方都要利用socket()函数创建套接字,然后将本机ip地址和端口通过bind()函数与套接字绑定。绑定后,可以直接使用sendto()函数向对方发送消息。使用recvfrom()函数可以接收指定端口的udp包,并通过返回的address结构获知发送方的ip地址和端口号。第四节 本章小结本章主要介绍了该系统开发的环境和平台,linux是一款流行的网络操作系统,由unix演化了来,具有丰富和网络功能,开发的函数库较多,功能强大。gcc是一款开源的编译器,有强大的编译调试的能力,使本系统的开发、测试,轻松了很多。最后介绍了本章的网络编程的一些知识,包括tcp/udp技术检测和一些系统开发用到的socket函数。第三章 系统的分析与设计第一节 需求分析一、问题定义本系统的问题概述如下:基本问题是linux以及网络编程的研究,基本目标是设计一个基于linux环境的心跳检测的系统来判断局域网的网络连接是否正常。 二、可行性研究可行性分析的任务不是研究如何解决问题,而是要用最小的代价在最短的时间内,确定问题定义阶段所定义的问题是否值得解决。一般情况下,主要从技术可行性、经济可行性和操作可行性三个方面论证系统开发的可行性。该系统可在小范围的局域网上进行使用,因此从可操作性来讲是可行的。其次,设计开发这样的一款心跳检测系统只需要几台电脑构成局域网就可以使用。下面主要从技术可行性进行分析:开发工具和环境linux是一款比较成熟的操作系统,它有unix演化发展而来,和unix有多相似之处。所用的函数包基本一致,再加上gcc的强大编译、调试的功能,对完成这个系统由很大帮助。 算法该系统不需要什么复杂的算法,只需掌握linux环境下的tcp/ip网络方面的知识,能够熟练运用linux下的网络编程和线程函数,就可以写出。幸运的是,通过查阅大量丰富的技术资料,我有信心解决这一问题。 自身素质因素通过大学四年的学习,我打下了坚实的专业基础,最重要的是学会了自主学习和查阅资料的能力,这都将为我今后的设计开发过程提供强有力的保障。通过以上分析,可以很确定这一系统的可行性,可以放心地开始下一阶段的任务了。三、用户需求本系统分为外围节点和主控节点的设计,它们有各自的功能:1、外围节点功能 外围节点所需要完成的功能相对简单,它只需要先发送登录报文进行注册,收到主控节点的反馈报文之后,定期(每隔一秒)发送心跳报文即可,不涉及太多功能。2、主控节点功能 主控节点是系统的关键部分,它负责接收登录报文和心跳报文,然后根据报文的内容来判断网络连接情况,可以说本系统的主要功能基本上由主控节点完成:完成接收心跳报文功能主控节点收到外围节点的登录报文后,就完成对外围节点信息的注册,包括外围节点的设备号和分配的槽口号等,并将槽口号返回给外围节点。完成接收心跳报文功能主控节点接收到心跳报文后,由于心跳报文中带有槽口号,主控节点根据槽口号查找外围节点注册表,修改响应信息。完成定期检查外围节点功能 主控节点要定期检查外围节点注册表,从而发现节点是否正常工作,如果不正常就报告响应的故障消息。四、系统整体用例图图3.1 系统用例图第二节 概要设计概括地说,概要设计进行数据设计/数据库设计和系统体系结构设计。其目的只是描绘出软件的总体框架,根据功能、性能需求和数据需求导出软件的数据结构和系统结构。一、设计指导思想 模块化模块是构成程序的基本构件,模块化就是把程序划分成独立命名且可独立访问的模块,每个模块完成一个子功能,把这些模块集成起来就构成了一个整体,可以完成指定的功能,以满助于用户需求。采用模块化原理可以使软件结构清晰,降低了系统的复杂性,使系统容易设计、容易修改,而且其推动了系统各部分的并行开发,提高了软件的生产效率。本心跳检测系统设计正是采用了模块化原理,在主控节点上有三个线程,每个线程看做一个模块,方便了主控节点功能的实现。 抽象化在对软件系统进行模块设计时,可以有不同的抽象层次,系统设计过程中的每一步都是对软件问题解法的又一次更高级抽象。可行性研究是对整个系统的抽象,需求分析则是对此心跳检测系统所要实现功能的抽象。二、心跳检测系统的整体结构图使用上节所提到的模块化等设计思想,先是对外围节点的发送报文的流程进行了设计,然后说对主控节点的完成外围节点注册,完成接收心跳报文,完成定期检查外围节点三个功能进行了一一的设计,下面是整个程序的结构图,如图3.2示。图3.2 程序结构图三、总体设计心跳检测的基本原理是每个结点周期性地向主控节点发送消息,主控节点根据外围节点发送来的消息判断这些节点的状态。整个心跳检测系统包括外围节点和主控节点两个部分,其结构如图3.3所示。心跳检测过程包括以下几个步骤:连接的建立 外围节点启动,将首先与事先约定的主控节点ip地址建立tcp连接,并向主控节点注册该外围节点的设备号信息。主控节点在接收到外围节点的注册报文后,将回送许可报文。外围节点在接收到许可报文后,将进入心跳检测状态。如果外围节点在5秒内没有连接到主控节点,或者发出注册报文后5秒内没有收到主控节点的许可报文,则睡眠10秒钟后重新与主控节点进行连接。心跳检测 外围节点每隔1秒向主控节点发送一次心跳报文。主控节点每隔1秒查询各个节点的心跳报文,如果在1秒内没有收到外围节点的心跳报文,则显示相应外围节点的网络连接出现问题。 图3.3心跳检测的结构图外围节点与主控节点建立连接时采用了tcp协议,而心跳检测过程中使用了udp协议。这是由于tcp协议可以保证传输的可靠性和顺序性,但是运行开销比较高,而udp协议虽然是一中不可靠的协议,但是传输开销比较小。因此,在嵌入式系统中,为了降低系统运行开销,可以将一些不重要的报文采用代缴比较低但是服务质量比较查的协议来实现。第三节 详细设计 详细设计是该系统的重点部分,介绍了系统具体是如何实现的,包括了心跳注册表的设计,报文格式的设计,主控节点和外围节点功能的设计。一、心跳表注册表的设计心跳注册表被设置成一个静态全局的结构体数组,当主控节点接收到外围节点的注册报文之后就为其在心跳注册表中找到一个空闲位置分配。而此后,主控节点在接收到外围节点的心跳报文后,也要相应的修改心跳注册表,判断节点是否出现故障也是通过扫描心跳注册表得知,所以这是个很关键的设计。结构体如下: struct heart_beatchar state;char flag;unsigned int device_id;struct sockaddr_in addr;#define heart_beat_table_size 64static struct heart_beat hb_tableheart_beat_table_size;表3.1statestate有idle和busy两种状态,各自的定义如下: #define idle 0#define busy 1只有设备正常工作时state才为busy,否则为idle。flagflag在主控节点接收到外围节点的心跳报文后设置为1,在检测心跳表判断设备是否工作时重新设置为0,用于标记外围节点是否坏掉。device_iddevice_id 是外围节点注册时向主控节点提供的,用于标识每个设备。sockaddr_in addrsockaddr_in addr是外围节点的ip地址。主控节点对心跳注册表的具体操作如下: 图3.4主控节点对心跳注册表的操作二、报文格式的设计主控节点和外围节点之间有三种报文:从外围节点到主控节点的登录报文(login),从主控节点到外围节点的响应报文(respond),以及从外围节点到主控节点的心跳报文(heart_beat)。其中前两者通过tcp协议发送,后者通过udp协议发送。在每种类型的报文前均有一个惟一的字节标识type,用于标识不同类型的报文。例如,在登录报文中,其type值为1;在响应报文中,其type值为2等。之所以采用这样的方法,是考虑到未来报文类型扩展的需要。由于各种报文均通过一个tcp端口接收,而接收端应用程序事先无法知道已经被操作系统接收的报文种类,因此也无法判断应该从recv()函数接口中读取多少字节。为了解决这一问题,接收端一般应该首先接收第一个字节,以判断当前报文的类型,然后根据此类型的大小决定从操作系统内存读取多少个字节到应用程序的数据结构中,以得到一个完整的报文。这三种报文格式为:#define login_type 0x01#define respond_type 0x02#define heart_beat_type 0x03登录报文:struct login char type;unsigned int device_id;表3.2type登录报文的type为0x01device_id外围节点注册时提供的设备号登录报文是外围节点向主控节点进行注册信息时,通过tcp连接发送的,外围节点需要提供自己的设备号即可,主控节点修改心跳注册表完成对外围节点的注册。响应报文:struct respond char type;int index;表3.3type登录报文的type为0x02index主控节点接收到外围节点注册成功时2提供给外围节点的槽口号主控节点收到外围节点的登录报文之后,必须要对外围节点进行响应,这时就需要发送具有反馈信息的respond报文,该报文包含了外围节点注册信息表给该外围节点提供槽口号index(第一个注册的为0,第二个注册的为1,一次类推),外围节点必须收到respond报文后才可以开始发送心跳报文。心跳报文:struct heart_beat char type;int index;unsigned int device_id;表3.4type登录报文的type为0x03index主控节点接收到外围节点注册成功时2提供给外围节点的槽口号,发送心跳报文时需提供槽口号以便主控节点修改hb_table表device_id外围节点注册时提供的设备号 心跳报文是外围节点定期向主控节点发送的udp报文,包含了外围节点的设备号和槽口号,主控节点根据槽口号来修改外围节点注册信息表,从而为定期扫描心跳注册表做准备。三、外围节点的设计心跳检测是外围节点软件系统中的一个模块。它被设计成一个独立的线程,执行如下算法:向主控节点发送登录(login)报文等待主控节点的反馈(respond)报文的响应 接收到respond报文转向4,否则休眠10秒后转向1根据respond报文的槽口号建立udp连接 向主控节点发送udp心跳报文 休眠1秒后转向5创建心跳检测线程其他处理建立与主的tcp连接向主机发送登录信息接受主机分配的槽口号通过udp协议发送心跳报文休眠10秒休眠100毫秒连接成功是否图3.5外围节点程序结构图2、外围节点的时序图3.6外围节点的时序图四、主控节点的设计 主控节点完成的功能比较复杂,包括接收外围节点的登录报文,接收外围节点的心跳报文,定期进行检查心跳注册表等。可以考虑采用三个线程分别实现这些功能,并通过一个共享的外围节点心跳表进行交互。 外围节点心跳表的数据结构如下所示。 #define idle 0#define busy 1#define heart_beat_table_size 64#define no_device 0struct heart_beatchar state;char flag;unsigned int device_id;struct sockaddr_in addr;static struct heart_beat hb_tableheart_beat_table_size;主控节点程序启动后,将首先初始化互斥量hb_table_lock,初始化hb_table数组中各个元素的state状态idle,然后创建三个线程。执行函数分别是accept_connect(),chenk_hb(),accept_hb()三个线程的结构图如下:图3.7 主控节点线程调用关系图1、 接收登录线程接收登录信息的线程执行如下算法: 创建套接字,绑定登录端口,并建立等待队列。 使用accept()函数等待外围节点的登录信息。 从套接字端口读取登录报文,获取外围节点的设备号device_id和ip地址。 检查hb_table中的各个表项。 如果当前设备号device_id已经存在于此表,且相关的状态为busy,则取此表项号index;否则分配一个state为idle的表项index。 设置hb_tableindex表项中的state为busy,设置此表项中的device_id何addr为外围设备的device_id和ip地址,设置此表项中的

温馨提示

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

评论

0/150

提交评论