为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

[新版]心跳检测(应用boost库)

2017-09-02 48页 doc 329KB 24阅读

用户头像

is_196623

暂无简介

举报
[新版]心跳检测(应用boost库)[新版]心跳检测(应用boost库) 题 目 学院名称 计算机科学与技术学院 指导教师 职 称 班 级 本07计算机01班 学 号 学生姓名 目 录 摘 要 随着Internet快速发展,大量的P2P出现给人们的生活交流带来许多便利。然而由于人们需求的不断提高,对于P2P系统的可靠安全行性,同时也提出了新的要求。对于覆盖世界的网络中,随时都有可能出现故障。对于研究者希望P2P系统有自动检测到故障的原因自动修复的功能。在这方面许多人都在不断的进行研究实验。 本文研究的主要方面是P2P存储系统与故障维护中的心跳检测技...
[新版]心跳检测(应用boost库)
[新版]心跳检测(应用boost库) 题 目 学院名称 计算机科学与技术学院 指导教师 职 称 班 级 本07计算机01班 学 号 学生姓名 目 录 摘 要 随着Internet快速发展,大量的P2P出现给人们的生活交流带来许多便利。然而由于人们需求的不断提高,对于P2P系统的可靠安全行性,同时也提出了新的要求。对于覆盖世界的网络中,随时都有可能出现故障。对于研究者希望P2P系统有自动检测到故障的原因自动修复的功能。在这方面许多人都在不断的进行研究实验。 本文研究的主要方面是P2P存储系统与故障维护中的心跳检测技术。心跳检测技术是一种检测网络连接故障的技术,根据服务端和客户端各自的心跳检测软件,相互之间发送消息即心跳报文来检测故障,判断网络连接是否正常,系统是否工作。这篇论文了一个能管理几百个外围节点的心跳检测系统。该系统是在Linux操作系统下,采用的TCP/UDP协议,以C/S模式,应用Boost库,以C++语言进行开发的。服务端为主控节点,客户端为外围节点,通过客户端发送心跳报文的方法来实现心跳检测。 关键词,P2P,心跳检测,Boost,Linux ABSTRACT Along with the Internet fast development, massive P2P appears for people's life exchange brings many conveniences. However, as a result of the people demand's unceasing enhancement, regarding the P2P system's reliable security line, simultaneously also set the new request. Regarding in the cover world's network, It has the possibility to present the breakdown. Regarding the researcher hoped that the P2P system has the automatic detection breakdown reason and the automatic repair function. In this aspect many people are researching. This paper mainly researches the heart beat technology of P2P memory system and failure detection. Heat beat technology is the technology that it detects network fault, as sending messages between server and client. And it can estimate whether the network and P2P system are working naturally. The paper introduces the P2P system can manage hundreds of the client nodes . The system designs in the Linux platform, using TCP/UDP protocol, Boost libraries, C++ language and on the basis of C/S model. Server acts as the master node, the client acts as the external nodes, through the heart beat messages sent by the client to achieve the heart beat detection methods. 引 言 随着网络技术的快速发展,网络拉近人们之间的距离,于此同时大量的基于网络的系统也不断的出现。在网络这个庞大的系统中,有成千上万的节点接入到网络中共享资源信息。对于这些成千上万节点靠我们人力管理是很难的,并且会经常的出现故障,这时我们需要系统自动的检测出网络中的故障所在。所以负责检测故障的心态检测技术就应运而生。 在P2P存储系统与故障修复中的心跳检测技术是基于C/S架构开发的网络检测系统。对于各类应用P2P软件,心跳检测技术是必不可少的一部分。P2P存储系统与故障修复是一个很庞大的部分,里面涉及到许多的算法。本论文对于故障修复进行详细的研究,仅仅是检测到那个节点发生了故障,没有正常连接到P2P系统中。以后随着这方面研究的深入,也许P2P系统检测与故障修复也会趋近于完善。 本人通过查找大量的资料对于心跳检测原理有一些了解。结合一些Linux网络编程的知识,为了能跨平台移植应用了Boost库开发。文章中对于设计的思想,和技术原理都进行了详细的描述。 第一章 绪论 1.1 心跳检测机制 在P2P系统中有成千上万个节点接入到系统中,这些节点随时都有可以发生故障,有可能是硬件故障,也可能是软件故障,导致客户节点无法正常接入到系统中,系统将无法得到本地系统的资源,甚至导致部分系统瘫痪。为了确保整个系统正常的工作,主控节点应该可以随时的知道其他节点当前是否正常工作。如果靠人力来监督这件事件是很难办到的,并且会造成很大的经济开销,而且响应时间较慢。心跳检测系统可以节省人力和经济,它根据外围节点定期发送的报 文来判断和网络连接是否出现故障。 心跳检测技术是P2P系统中常见的故障检测方法。在心跳检测技术的原理是外围节点定期的向主控节点发送心跳报文,主控节点定期的检测是否接收到外围节点发送的报文,主控节点定期时间段大于外围节点时间段,主控节点没有接收到响应节点的心跳报文,则认为此节点或者相关的网络出现故障,并向管理者报告。 特点:(1)基于C/S模式,半结构化的P2P存储系统中,服务端判断客户端是否正常运行,一般采用定时发送简单的心跳检测报文,如果在定期内没有收到节点的相应报文,则判断网络出现故障,同时也可以用ping方法来检测网络是否连接正常,但是此方法不能够判断出系统崩溃等其他情况。 (2)发送报文方可以是客户端(外围节点),也可以是服务端(主控节点),这方面设计是很宽松的,看你实际的需要。本人采用的是客户端发送报文,服务端不给予回复,服务端只是定期的检查是否接收到报文。 (3)检测方法是客户端(外围节点)每隔几秒发送心跳报文给服务端(主控节点)。服务端仅仅是检测报文是否存在,不回复给客户端(外围节点)。如果服务端在规定时间内没有收到客户端信息视为连接中断。 (4)心跳检测模块,可以是挂接在系统中,当需要修改时,可以将其修改 在挂接到系统中。 1.2 本文设计的P2P存储系统与故障检测模块 前面也介绍了心跳检测系统的概念,特点,原理,作用。下面我来介绍我所设计的系统。该系统主要是管理几百个外围节点,主要相关的网络编程的知识,没有数据库存储的相关知识,因此该系统所占用的内存空间较少,还有本系统主要是应用在局域网中,实现起来的网络连接是比较简单的,测试起来相对容易一些。本系统实现了比较基础的功能,对于P2P存储系统与故障检测来说,还有许多功能没有完善的实现,例如:当主控节点发现外围节点出现故障,现在假如主控节点为P2P半结构系统中的顶层节点,外围节点为超级管理节点,下面还有客户节点。当顶层节点检测到超级管理节点发生故障时,怎样才能其他节点中选择出,网络连接很好,节点不容易出现故障的节点,作为超级管理节点。这里就不但要检测故障,还要对故障进行修复,这需要很多的评估算法和策略。这也是一些研究者的研究方向。还有物理空间和虚拟空间之间的差距,网络延迟等问题。对于这些方面我进行深入的研究和涉及。这些还需要更多的时间去研究,实验,实现。 本人的设计在Linux平台下,采用C/S模式,应用Boost库,用C++语言实现。服务端充当主控节点,客户端充当外围节点。外围节点先发送TCP报文和主控节点建立连接。连接成功后,将外围节点的信息保存在主控节点中。外围节点向主控节点发送报文采用UDP协议。每隔1秒外围节点向主控节点发送一次心跳报文,主控节点每隔8秒检测一下是否有相应节点的心跳报文,根据节点心跳报文的有无来确定网络连接是否正常。 1.3 本章小结 本章介绍了P2P存储系统中的心跳检测技术,介绍了心跳检测的概念,心跳检测的原理,优点。使人们有了一个大致的了解。最后介绍了我自己设计的故障检测系统的概况,包括其优缺点和实现情况。 第二章 开发环境,工具和技术 2.1 Linux的介绍 Linux是一套免费使用和自由传播的类Unix操作系统,它主要用于基于Intel x86系列CPU的计算机上。这个系统是由全世界各地的成千上万的程序员设计和实现的。其目的是建立不受任何商品化软件的版权制约的、全世界都能自由使用的Unix兼容产品。 Linux的出现,最早开始于一位名叫Linus Torvalds的计算机业余爱好者,当时他是芬兰赫尔辛基大学的学生。他的目的是想设计一个代替Minix(是由一位名叫Andrew Tannebaum的计算机教授编写的一个操作系统示教程序)的操作系统,这个操作系统可用于386、486或奔腾处理器的个人计算机上,并且具有 Unix操作系统的全部功能,因而开始了Linux雏形的设计。 Linux以它的高效性和灵活性著称。它能够在PC计算机上实现全部的Unix特性,具有多任务、多用户的能力。Linux是在GNU公共许可权限下免费获得的,是一个符合POSIX标准的操作系统。Linux操作系统软件包不仅包括完整的Linux操作系统,而且还包括了文本编辑器、高级语言编译器等应用软件。它还包括带有多个窗口管理器的X-Windows图形用户界面,如同我们使用Windows NT一样,允许我们使用窗口、图标和菜单对系统进行操作。 Linux之所以受到广大计算机爱好者的喜爱,主要原因有两个,一是它属于自由软件,用户不用支付任何费用就可以获得它和它的源代码,并且可以根据自己的需要对它进行必要的修改,无偿对它使用,无约束地继续传播。另一个原因是,它具有Unix的全部功能,任何使用Unix操作系统或想要学习 Unix操作系统的人都可以从Linux中获益。 Linux的优点: (1)低廉性:基于其低廉成本与高度可设定性,Linux常常被应用于嵌入式系统中,例如:机顶盒,移动电话,及行动装置等等。在移动电话上,Linux已经成为与SymbianOS,Windows Mobile系统并列的三大智能手机操作系统之 一。例如:谷歌开发的Android手机操作系统。 (2)广泛性:基于Linux的开源性给人们带来了巨大的诱惑,Linux的应用越来越广,学习Linux系统的人也越来越多,在学习的同时也可以参与到Linux系统的开发中去。 (3)安全性:不过Linux由于支持者众多,有相当多的热心团体、个人参与开发,因此可以随时获得最新的安全信息,并随时更新,相对较安全。 (4)稳定性:Linux是基于UNIX概念而开发出来的操作系统,具有与UNIX系统相似的程序接口和操作方式,继承了UNIX稳定且有效率的特点。安装Linux操作系统的主机连续运行1年以上不曾死机、不必关机是很平常的事。 本人所用的Linux操作系统是Ubuntu 11.4版本,这个系统界面设计也是比较新颖,功能比较强大。对于软件开发人员来说初步了解Linux这个系统很有效果。如下图: 图2.1 2.2 GCC的简介 2.2.1 GCC的介绍 GCC(GNU Compiler Collection,GNU编译器套装),是一套由 GNU 开发的编程语言编译器。 以 GPL 及 LGPL 许可证所发行的自由软件,也是 GNU的关键部分,亦是自由的类Unix及苹果电脑 Mac OS X 操作系统的标准编译器。 GCC 原名为 GNU C 语言编译器,因为它原本只能处理 C语言。GCC 很快地扩展,变得可处理 C++。之后也变得可处理 Fortran、Pascal、Objective-C、Java, 以及 Ada与其他语言。使用GCC编译程序时,编译过程可以被细分为四个阶段:预处理(Pre-Processing),编译(Compiling),汇编(Assembling),链接(Linking)。如今的GCC借助于它的特性,可以交叉编译,即在一个平台下编程另一个平台的代码。GCC是完全免费的自由软件,加之其强大的功能所以深受广大用户的喜爱。 2.2.2 GCC的基本规则 GCC编译器能将C、C++语言源程序、汇程式化序和目标程序编译、连接成可执行文件,如果没有给出可执行文件的名字,GCC将生成一个名为a.out的文件。 在Linux系统中,可执行文件没有统一的后缀,系统从文件的属性来区分可执行文件和不可执行文件。而GCC则通过后缀来区别输入文件的类别,下面我们来介绍GCC所遵循的部分约定规则。 .c为后缀的文件: C语言源代码文件; .a为后缀的文件: 是由目标文件构成的档案库文件; .C,.cc或.cpp 为后缀的文件: 是C++源代码文件; .h为后缀的文件: 是程序所包含的头文件; .i 为后缀的文件: 是已经预处理过的C源代码文件; .ii为后缀的文件: 是已经预处理过的C++源代码文件; .m为后缀的文件: 是Objective-C源代码文件; .o为后缀的文件: 是编译后的目标文件; .s为后缀的文件: 是汇编语言源代码文件; .S为后缀的文件: 是经过预编译的汇编语言源代码文件。 2.2.3 GCC的执行过程 虽然我们称GCC是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤?预处理(也称 预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)。 命令GCC首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。接着调 用cc1进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言 源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。当所有的目标文件都生成之后,GCC就调用ld来完成最 后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的档案库中 连到合适的地方。 2.2.4 GCC的基本用法和选项 在使用GCC编译器的时候,我们必须给出一系列必要的调用参数和文件名称。gcc编译器的调用参数大约有100多个,其中多数参数我们可能根本就用不到,这里只介绍其中最基本、最常用的参数。 GCC最基本的用法是?gcc [options] [filenames] 其中options就是编译器所需要的参数,filenames给出相关的文件名称。其中[options]的值可以为下列值: -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类,cpp在当前目录中搜寻头文件, 这个选项的作用是告诉cpp,如果在当前目录中没有找到需要的文件,就到指定的dirname目录中去寻找。在程序设计中,如果我们需要的这种包含文件分 别分布在不同的目录中,就需要逐个使用-I选项给出搜索路径。 -Ldirname,将dirname所指出的目录加入到程序函数档案 库文件的目录列表中,是在连接过程中使用的参数。在预设状态下,连接程序ld在系统的预设路径中(如/usr/lib)寻找所需要的档案库文件,这个选项 告诉连接程序,首先到-L指定的目录中去寻找,然后到系统预设路径中寻找,如果函数库存放在多个目录下,就需要依次使用这个选项,给出相应的存放目录。 -lname,在连接时,装载名字为“libname.a”的函数库,该函数库位于系统预设的目录或者由-L选项确定的目录下。例如,-lm表示连接名为“libm.a”的数学函数库。 2.3 Boost库的简介 2.3.1 Boost的介绍 Boost库是为C++语言标准库提供扩展的一些C++程序库的总称。 Boost库由Boost社区组织开发、维护。其目的是为C++程序员提供免费、同行审查的、可移植的程序库。Boost库可以与C++标准库完美共同工作,并且为其提供扩展功能。Boost库使用Boost License来授权使用,根据该协议,商业的非商业的使用都是允许并鼓励的。 Boost社区建立的初衷之一就是为C++的标准化工作提供可供参考的实现,Boost社区的发起人Dawes本人就是C++标准委员会的成员之一。在Boost库的开发中,Boost社区也在这个方向上取得了丰硕的成果。在送审的C++标准库TR1中,有十个Boost库成为标准库的候选。在更新的TR2中,有更多的Boost库被加入到其中。从某种意义上来讲,Boost库成为具有实践意义的准标准库。 大部分boost库功能的使用只需包括相应头文件即可,少数(如正则表达式库,文件系统库等)需要链接库。里面有许多具有工业强度的库,如graph库。 很多Boost中的库功能堪称对语言功能的扩展,其构造用尽精巧的手法,不要贸然的花费时间研读。Boost另外一面,比如Graph这样的库则是具有工业强度,结构良好,非常值得研读的精品代码,并且也可以放心的在产品代码中多多利用。 2.3.2 Boost库的编译方法 从Boost网站(www.boost.org)上下载Boos库文件.要编译Boost库,首先要获得bjam文件,这个文件也可以从网站上直接下载编译好的,但是还是不如自己编译的好。Boost库具有可移植性,所以在不同的操作系统里编译方法略有区别。在Windows下,运行bootstrap.bat得到bjam文件,然后运行bjam文件。 在Linux下,运行bootstrap.sh得到bjam文件,然后运行bjam文件。有的上介绍说:完全编译Boost很费时间,本人编译没有花费太多的时间。也可以应用到哪个库编译那个库。 2.3.3 本人所用到的Boost库 主要应用并发编程库 a) Asio库:基于操作系统提供的异步机制,采用前摄设计模式实现了可移植的异步IO操作。 b) Interprocess库:实现了可移植的进程间通信功能,包括共享内存、内存映射文件、信号量、文件锁、消息队列等。 c) MPI库:用于高性能的分布式并行开发。 d) Thread库:为C++增加线程处理能力,支持Windows和POSIX线程 涉及到Boost库。 Bind库:绑定器的泛化,已被收入TR1。 Date Time 库:一个非常全面灵活的日期时间库。 Filesystem库:可移植的文件系统操作库,可以跨平台操作目录、文件,已被TR2接受。 System库:使用轻量级的对象封装操作系统底层的错误代码和错误信息,已被TR2接受。 2.4 运用到的网络编程技术 2.4.1 socket与asio库介绍 在Linux系统中,最常用的网络应用编程结构是UNIX BSD的套接字接口。Socket编程有字节流和数据报两种主要类型,分别对应TCP协议和UDP协议。其中字节流socket定义了一种可靠的面向连接的服务,实现了无差错无重复的顺序数据传输。数据报socket定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且无法保证可靠无差错。无连接服务器一般都是面向事 务处理的,一个请求一个应答即为客户和服务器之间的交互。asio库它使用了大量的类和函数封装了socket API,提供了一个现代C++风格的网络编程接口,支持TCP,TCMP,UDP等网络通信协议。但asio的异步操作并不局限于网络编程,它还支持串口读写,定时器,SSL等功能,而且asio是一个很好的富有弹性的框架,可以扩展到其他有异步操作的需要的领域。 asio中关于TCP协议的编程 (1)io_service ios asio程序必须声明一个io_service对象 (2)ip::tcp::socket sock(ios) 创建一个TCP的socket对象 (3)ip::tcp::endpoint ep(ip::address::from_string(“127.0.0.1”),6688) 创建连接端点 (4)sock.connect(ep) socket连接到端点 asio 中关于UDP协议的编程 asio中的UDP协议通信与TCP处理流程类似,但是因为UDP协议是无连接的,所以不要建立连接,使用send_to()和receive_from()就可以直接通过端点发送数据。 服务端: (1)ip::udp::socket sock(ios, ip::udp::endpoint(ip::udp::v4(), 6699)) 创建一个UDP的socket对象 (2)char buf[1] 一个临时用的缓冲区 (3)ip::udp::endpoint ep; 要接受连接的远程端点 (4)system::error_code ec; sock.receive_from(buffer(buf), ep, 0, ec); 阻塞等待远程连接,连接的端点 信息保存在ep对象中。 客户端: (1)ip::udp::endpoint send_ep(ip::address::from_string(“127.0.0.1”), 6699); 连接端点 (2)ip::udp::socket sock(ios); 创建udp socket对象 (3)sock.open(ip::udp::v4()); 使用ipv4打开socket (4)char buf[1] sock.send_to(buffer(buf), send_ep) 向连接端点发送连接数据 IP地址的获取与转换 (1)ep.address() 获取端点ep的IP地址 (2)ip::address addr 声明一个ip地址对象 (3)addr = addr.from_string(“127.0.0.1”) 从字符串产生IP地址 (4)addr.to_string() 将地址转为字符串 (5)addr.to_v4() 将IP转化ipv4的地址 (6)addr.to_v6() 将IP转化ipv6的地址 附加:线程创建函数 thread m_th(bind(&HeatBeat::MainThread,this)) (1)m_th 线程名称 (2)HeatBeat 类名称 (3)MainThread 函数名称(这是一个无参函数) 也可以是一个有参函数 (4)bind 将函数,线程绑定在一起 2.4.2 TCP与UDP协议应用介绍 (1)TCP应用介绍 在基于TCP协议的程序设计中一般采用C/S的程序设计模式。在服务端首先使用socket()函数创建套接字,然后使用bind()函数将本机的IP地址和服务端的绑定至套接字,并通过listen()建立等待队列,使用accept()函数等待客户端的连接。accpet()函数将一直阻塞,直到有一个客户端连接到本地服务器端口为止。该函数将返回一个新的套接字值,随后服务器就可以通过新的套接字接口与连接上的客户端利用rend()和write()函数进行交互。 客户端在在访问服务端是首先要通过socket()函数调用,然后通过connet()函数连接服务器端IP地址和相应的服务器端口号。连接成功后,就可以通过read()或write()与服务器进行数据交互了。C/S模式下的TCP应用程序框架如下图: 服务器 Socket():创建套接字 Bind():绑定本机地址和 端口号 客户端 Listen():设置等待队列Socket():创建套接字 建立请求Accept():等待客户端连Connect()连接服务器接 Read()或write():与客Read()或write():与服 户端交换数据务器交换数据 图2.2 (2)UDP应用介绍 对于UDP协议的相对于TCP的应用来说是比较容易的,它不用预先建立连 Close()关闭特定客户端的Close()关闭套接字接。服务端和客户端都要用socket()创建套接字,然后将本机IP地址和端口通过套接字 bind()函数与套接字绑定。绑定后,可以应用sendto()函数发送数据包,可以通过recvfrom()函数接收UDP包,应用address结构获知发送方的IP地址和端口号。 2.5 本章小结 本章先后介绍了 Linux ,GCC ,Boost 库,和网络编程技术。可以让人们对其有一些初步的了解。Linux是开源的一款操作系统,具有较多的开发的函数 库,功能强大。GCC是一款开源的编译器,有强大的编译调试的能力。Boost库最重要的特点是它解决了C++语言难以移植的特性。并且相对于STL来说功能也很强大。最后介绍的网络编程的知识,是一般P2P系统中常用的知识,TCP和UDP也是常用的协议。 第三章 系统分析与设计 3.1 需求分析 3.1.1 问题定义 超级节点心跳检测:P2P(Peer-to-Peer:对等网络)利用用户桌面闲散资源构成一个自组织、可扩展的存储系统(或者叫文件共享系统),其结合新型网络通讯技术和存储架构技术,提供一个高可用的数据共享资源。P2P存储系统由多 种拓扑结构组成,底层的覆盖网络决定了节点的组织策略。半结构化拓扑结构结合了分布式和集中式拓扑各自的优点,心跳模块负责检测节点的在线状态,及时启动数据修复策略和副本恢复。 3.1.2 可行性分析 可行性分析的任务是要用最小的代价在最短的时间内,确定问题定义阶段所定义的问题是否值得解决。 可行性分析主要包括操作可行性,经济可行性,技术可行性。 操作可行性:本模块是应用在校园局域网中,scool共享文件系统中。用于学生资料的传输。 经济可行性:对于毕业设计来说,经济无从谈起。 技术可行性: 1)开发工具和环境:Linux操作系统(Ubuntu), GCC(g++),Boost( 库。 (2)算法:该系统不需要复杂算法,了解TCP/IP网络方面知识,能够掌握Boost库下的网络编程和线程函数。对于C++语言需要复习一下,Boost库只是应用个别的库需要自己学习了这方面的知识。对于Linux系统需要熟练应用一下。 3.1.3 用户需求 本系统要实现一个基于P2P技术的校园文件共享系统中的一部分超级节点故障检测,P2P系统首要要确定的是底层的覆盖网结构,这里为了便于控制系统中的节点,采用的是如下的三层等级结构: 图3.1 我们所做的系统就是应用在顶层节点和超级节点之间。 外围节点(客户端)功能 对于心跳检测来说:外围节点的需要完成的功能相对简单,它只是需要先发送登录进行注册,收到主控节点的反馈报文之后。定期(每隔一秒)发送心跳报文即可,不涉及太多功能。 主控节点(服务端)功能 主控节点是系统的关键部分,它负责接收登录报文和心跳报文,然后根据是否接收到相应节点的报文来判断网络连接情况(注:这里不是根据报文内容来判断的)。主控节点需要完成: (1)完成接收登录报文功能(超级节点登录模块中) 主控节点收到外围节点的登录报文后,就完成外围节点的注册,包括外围节点的ID和设备状态等信息。这一块在模块划分的时候,和心跳检测隔离开来了。 (2)完成接收心跳报文功能 主控节点接收到心跳报文后,不会去解析报文的内容,而是去检测发送报文的IP地址,而且也不回复。将修改注册表中的状态。 (3)完成定期检查外围节点是否存在的功能 主控节点要定期检测外围节点注册表,从而发现节点是否正常工作,如果不正常就报告给超级节点管理模块进行处理。 模块用例图 图3.2 3.2 概要设计 概要设计包括:数据设计,软件结构设计,接口设计,过程设计。目的是描绘出一个整体的框架,根据功能,性能需求和数据需求导出软件的数据结构和系统结构。 3.2.1 设计指导思想 (1)模块化 模块是构成程序的基本构件,模块化是把程序划分成独立命名且可独立的访问的模块,每个模块完成一个子功能,最后把这些模块集成起来就构成一个整体,可以完成指定的功能,以满足需求。模块化的好处有助于代码的复用,挂接,和修改,而且其推动了系统各部分的并行开发,提高效率。 整个scool文件共享系统都是采用模块化原理。对于这个心态检测模块也需 要模块化,这样可以使软件结构更加的清晰。在主控节点上原本应该有三个线程的,但是节点登录被划分到超级节点登录模块中去了,所以对于心态检测模块来说就只有两个线程了。本人将每一个线程看做是一个模块,这样方便实现和修改。外围节点可以为一个模块因为就有一个功能用于发出心态消息,发送登录报文也被划入了用户的登录。 (2)抽象化 在对软件系统进行模块设计时,可以有不同的抽象层次,系统设计过程中的每一步都是对软件问题解法的又一次更高级抽象。可行性研究是对整个系统的抽象,需求分析则是对此心跳检测系统的所要实现功能的抽象。 3.2.2 P2P存储系统故障检测模块(心跳检测)的整体结构图 用模块化的思想进行分析,对外围节点的发送报文的流程进行设计。其过程为首选发送登录报文,当收到主控节点的回复才发送心跳报文。对主控节点来说:当接收登录报文,扫描注册表,有,则设定状态,没有,加入到注册列表中。给外围节点回复,接收外围节点心跳报文,将设定注册表状态,定期的检查注册表。下面是整个模块的结构图 心跳检测模块 主控节点 外围节点 接收登录报文 发送登录报文 写入/修改注册表 回复外围节点 发送心跳报文 接收心跳报文 定期扫描注册表外 围节点状态 将出现故障节点发 送给超级节点管理 模块 图3.3 3.2.3 总体设计 心跳检测是分布式系统或分布式嵌入式系统常见故障检测方法。外围节点周期性向主控节点发送心跳报文。如果在一段时间之后,主控没有收到心跳报文,则认为节点故障(排除网络导致的故障)。 (1)连接的建立 外围节点启动后,将首先与事先约定的主控节点IP地址建立TCP连接,并向主控节点注册改外围节点的设备号信息。主控节点在接收到外围节点的注册报文后,将回送许可报文。外围节点在接收到许可报文后,进入心跳检测状态; (2)心跳检测 外围节点每隔1秒向主控节点发送一次心跳报文。主控节 点每隔8秒查询各个外围节点的心跳报文,如果在8秒内没有接收到外围节点的心跳报文,则报错 在P2P系统中,希望检测远程节点是否正常工作应用TCP和UDP协议不同地方应用: (1)字节流socket——TCP:可靠、面向连接、无差错无重复的顺序数据传输。通过TCP建立节顶层节点和超级节点(超级节点和客户节点)之间的链接,得到主机的IP 和ID号。 (2)数据包socket——UDP:无连接、无序、相互独立的报文,一般面向书屋处理的,一个请求和一个应答就完成了客户程序和服务程序之间的交互应用UDP协议,进行顶层节点和超级节点(超级节点和客户节点)之间的通信。 心跳检测结构图: 图3.4 外围节点与主控节点建立连接是采用了TCP协议,而心跳检测过程中使用了UDP协议。这是由于TCP协议可以保证传输的可靠性和顺序性,但是运行开销比较高,而UDP心跳虽然是不可靠的协议,但是存储开销比较小。因此,在 嵌入式系统中,为了降低系统运行开销,可以将一些不重要的报文采用代价比较低,但是服务质量比较差的协议来实现。 3.3 详细设计 详细设计是该系统的重点部分,介绍了系统具体是如何实现的,包括心跳报文格式,心跳注册表设计,主控节点和外围节点功能的设计。 3.3.1 心跳报文格式 本人在心跳报文设计上,似乎有一些投机取巧的行为。本人在心跳报文中没有添加任何实质上的信息,仅仅只是定义了一个随机的字符缓冲区 char buf[1];,运用send_to()函数去发送这个缓冲区内容,就是像神经冲动一样,定时的给主控节点一个脉冲。相关编码如下: ip::udp::endpoint send_ep; char buf[1]; sock.send_to(buffer(buf),send_ep); 注:登录报文属于超级节点登录模块范围,所以这里没有介绍。 3.3.2 心跳注册表的设计 心跳注册表被设置成一个动态的全局的向里(vector),当主控节点接收到外围节点登录报文,超级节点登录模块,将节点信息添加到登录注册表中(注:这部分不包括在心跳检测模块范围内),然后再将节点信息发送给心跳检测模块,这时心跳检测模块是以一个观察者是身份来监督这些外围节点是否正常运行。当心跳检测模块收到超级节点登录模块发送来的外围节点的信息,将节点信息打包,结构体中: struct SuperNodeInf { int notify_type; //标识符 1代表在线 0 代表断线 -1代表已经退出登录 string s_node_ID; //ID号时主键值是不可以改变的 unsigned long uip; }; notify_type 值 1:代表节点正常工作 0:代表节点故障断线 -1:代表节点正常退出 s_node_ID 每一个节点都给非配一个ID号 它作为主键值是不可以改变的 uip uip为节点的ip地址 表3.1 然后再将节点信息加入向量中 vector v中。 主控节点对心跳注册表的具体操作如下: 主控节点 赋值:notify_type = 1, 接收心跳报文并且获得发定期扫描心跳检测注册表s_node_ID,uip都是由超级送报文节点的IP地址,如果将节点notify_type为0的节 节点管理模块给定。如果这节点的notify_type为1则不点ID报告给超级节点管理 模块 节点曾经在注册列表中存改变,如果为0则将值改变 在过就只改变 notify_type为1 和uip地址 心跳检测注册表 图 3.5 3.3.3 主控节点和外围节点功能设计 主控节点和外面节点的总结构如图: 图3.6 (1)外围节点功能设计: 外围节点的功能很简单是向主控节点发送心跳数据报(注:登录报文不在这个模块内),它在整个客户端是是一个小的模块,所以它被设计成一个独立的线程。算法也很简单:将缓冲区随机的内容每隔1秒发送给服务端就可以了。 包含发送登录报文的外围节点流程图: 创建心跳检测线程 建立与主空节休眠10秒 点TCP连接 其他处理 连接成功, 向主控节点发送登录信息 接收分配的ID号 通过UDP协议发送心跳 休眠1秒 报文 图3.7 下面画出的是包含登录报文的外围节点的时序图 图3.8 (2)主控节点功能设计 主控节点完成的功能比较复杂,包括接收外围节点的心跳报文,定期进行性检查心跳注册表,通过两个线程实现这些功能。当注册的时候,与超级节点登录模块。当检测出故障时候,与超级管理模块关系。有关节点信息和心跳检测注册表数据结构设计如下 enum NotifyType { //通知的类型 NOTIFY_ADD, //添加 NOTIFY_REMOVE, //移除 }; 注: NotifyType当超级节点登录模块传递登录节点信息时调用。 struct SuperNodeInf { int notify_type; //标识符 1代表在线 0 代表断线 -1代表已经退出登录 string s_node_ID; //ID号时主键值是不可以改变的 unsigned long uip; }; vector v; 注:心跳检测注册表数据结构。 主控节点程序启动后,首先初始化向量vector v,因为节点信息是通过超级节点管理模块传递给故障检测模块的。所以只是简单的将节点的信息打包加入到注册链表中。并把节点状态的标识符notify_type设置为1代表节点,节点在线。 SuperNodeInf s; s.notify_type = 1; s.s_node_ID = nodes; s.uip = uip; 节点信息打包过程, v.push_back(s); 将节点信息加入心跳注册表。 将建立vector向量,将节点中的信息放在向量中。将服务端分为两个线程。 m_th(用于定期检查vector中节点Notify_type的值,为1将其改变为0,为0则不改变,将其报告超级节点管理模块,休眠1秒在继续检测) O_th(用于接收客户端发来的消息,如果有节点发来消息,将该在vector中的Notify_type的值改为1)。 主线程的流程图: 服务端流程图 主线程 初始化 将节点信息添加到向量 vector v 将节点信息标识位 Notify_type=1 主线程m_th休眠1秒 Notify_type、 =0, 锁定互斥量mu 将Notify_type=0 报告给超级节点管理模块 N Y 所有节点检测 N 完毕, Y 图3.9 下面是m_th线程中用于定期检测的函数实现代码 ////////////////////////////////////////////////////////////////////////// //函数: MainThread() //作用:主线程用于检测 //备注:每隔一段时间秒检测一下向量中到元素的notify_是否有为0点 //如果有报告超级节点管理模块 并且将notify_type = 0 ////////////////////////////////////////////////////////////////////////// void HeatBeat::MainThread() { try { while(true) { for(int i = 0;i < v.size(); i++) { { mutex::scoped_lock lock(mu); //互斥锁 if(v[i].notify_type==1) v[i].notify_type=0; else cout<<"不存在:"< Notify_type 图3.11 主线程和定期检测心跳注册表线程之间的关系,只有对中间这个心跳检测表的操作。它们的操作都是改写注册表中的notify_type节点的状态位。 3.4 本章小结 本章主要介绍了需求分析,概要设计,详细设计。本章的主要重点是在主控节点和外围节点的功能实现实现上。又描述了本系统的用例图。在详细设计里则是主控节点和外围节点的设计思路和执行算法上。需要注意一点是心跳报文中没有实质的内容。而且通过获取IP地址来说确定谁发的心跳报文。但是在这种情况下,会出现问题。咱们举例一下:当你的电脑上登录两个QQ时,它们的IP地址是相同的,这样通过IP地址是无法将他们区分开来的,但是这里我为什么这样做呢,是因为我们这里所做的超级节点心跳检测,对超级节点来说是无法将两个客户端同时登录的。 第四章 心跳检测系统的实现 4.1 Linux下的开发环境 前面的章节已经介绍了GCC的相关内容,该设计中有两个.cpp文件,client.cpp和s_heat_beat.cpp文件,分别是外围节点和主控节点的编码文件。然后我们将这两个文件进行编译就生成了可执行文件client和s_heat_beat。如下图: 图4.1 在这个图片中我们可以看见一个makefile文件。这个文件是用来编译client.cpp和s_heat-beat.cpp时调用的。下面我们看一下makefile里的内容。如下图: 图4.2 我们所用的是GCC中的g++和Boost库,图中BOOST_LIB_PATH := /usr/local/lib/boost/,因为要用到Boost库,所以这个地方给了Boost库的路径。图中下面的语句给出了文件所需用到的Boost库中的libboost_thread.a 和libboost_system.so.1.46.0。 g++ s_heat_beat.cpp -o s_heat_beat 是编译s_heat_beat.cpp文件 g++ client.cpp -o client 是编译client.cpp 文件 这样正确编译就可以生成可执行文件s_heat_beat 和 client。 注:这里需要特别的介绍一下我用的不是集成环境,而是把Linux下文本文档gredit打造成集成环境。这个很简单就是把gredit按一些插件,就可以把终端快速浏览等加入懂gredit中使它成为一个简单的集成环境。 4.2 程序的实现 4.2.1 外围节点的实现 该设计中没有登录报文,登录报文这一块归超级节点登录模块。在超级节点中登录报文和响应报文构成了握手过程(或者叫面向连接过程)。主控节点会分配给外围节点一个ID。这个ID号用于心跳检测的时候,出现故障报告给超级节点管理模块。外围节点的功能很少就只有发送心跳检测报文。每隔1秒它发送一次心跳检测报文。 (1)时间问题的讨论 考虑心跳检测模块接收到超级节点管理模块传递的节点信息和第一个心跳报文之间的时间间隔。如果超级节点管理模块在t时刻接收到登陆报文,将分配外围节点相应的ID号,并设置notify_type = 1 表示节点状态为在线;如果在此过程结束后就执行定期检查线程,则将此notify_type值设置为0;如果在下一次定期检查线程未执行之前还未收到心跳报文,则会导致心跳检测模块认为节点故障处在断线状态。 接收节点定期检测定期检测 信息 线程 线程 n秒 t 第一个心跳报文必须在此区域内到达 a: 得到节点信息和第一个心跳检测报文的时间间隔 图4.3 考虑两个心跳报文之间的时间间隔。如果在t时刻主控节点接收到前一个心跳报文,而随后执行定期检查线程,则后续心跳报文必须在下一次定期检查线程之前到达,否则将导致定期检查线程判断连接中断。 前一个心定期检测定期检测 跳报文 线程 线程 n秒 t 后续心跳报文应该在此区间内到达 b:两个心跳报文的时间间隔 图4.4 考虑发生故障时的最长发现时间。如果t时刻主控节点接收到最后一个心跳报文,而定期检查线程刚刚在接收心跳报文之前执行,则需要执行两次定期检查线程才能发现外围节点的故障。因此,最长发现时间为2n秒 定期检测定期检测定期检测最后一个 线程 线程 线程 心跳报文 n 秒 n秒 notify_type = 1 notify_type = 0 发现故障 c:发现故障的最长时间 图4.5 对于外围节点来说登录报文和心跳报文之间的时间间隔需要多少秒,n秒(实际应用中设定n=1),这对于广域网环境下的应用是不够的,解决办法,增加一个状态,设置notify_type初始值为10,在定期检查中,发现表项notify_type>0,则将notify_type减1;如果notify_type为0,认为外围节点故障。 (2) 外围节点实现代码段 Client(io_service& io):ios(io),send_ep(ip::address::from_string("127.0.0.1"),6890) { int i=0; while(true) { thread c_th(bind(&Client::start,this)); this_thread::sleep(posix_time::seconds(5)); cout<<"第"<
/
本文档为【[新版]心跳检测&#40;应用boost库&#41;】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索