基于java的判断DTU超时功能的研究与设计毕业论文设计1_第1页
基于java的判断DTU超时功能的研究与设计毕业论文设计1_第2页
基于java的判断DTU超时功能的研究与设计毕业论文设计1_第3页
基于java的判断DTU超时功能的研究与设计毕业论文设计1_第4页
基于java的判断DTU超时功能的研究与设计毕业论文设计1_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

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

文档简介

1、安安 徽徽 农农 业业 大大 学学 毕毕 业业 论论 文(设计)文(设计) 论文题目论文题目 基于基于 java 的判断的判断 dtu 超时功能的研究与设计超时功能的研究与设计 姓 名 詹 步 康 学 号 09101009 院 系 信息与计算机学院 专 业 通信工程 指导教师 张武 职 称 副教授 中国中国合肥合肥 二二o一三一三 年年 五 月月 安徽农业大学学士学位论文(设计)开题报告安徽农业大学学士学位论文(设计)开题报告 课题名称 基于 java 的农业物联网中间件的判断 dtu 超时功能的研究和设计 课题 来源 导师指定 学生姓名詹步康 专 业 通信工程学号09101009 指导教师姓

2、名张武 职 称 副教授 研 究 内 容 1研究分析 dtu 超时功能的作用。 2对 dtu 超时功能的应用原理进行分析: 1)dsc 启动定时器轮询并获取用户最后一次与 dsc 通讯的时间。 2)获取当前时间并与最后一次登录时间比较,取其差值。 3)该值超过事先定值则断开用户 dtu 与 dsc 数据中心的连接。 3对以上工作过程的需要进行编程并进行模拟测试。 研 究 计 划 3 月初3 月中 调研、查资料。 3 月中4 月初 研究并分析超时功能的作用及其应用原理。 4 月中5 月初 构建系统框架,编程。 5 月初5 月中 对系统进行调试、运行并修改。 5 月中 撰写毕业设计论文。 特 色 与

3、 创 新 系统稳定,抗干扰能力强 应用该功能可以节省不必要的流量花费 指 导 教 师 意 见 教 研 室 意 见 学 院 意 见 基于基于 javajava 的的农业物联网中间件农业物联网中间件的研究的研究 判断判断 dtudtu 超时功能的研究和设计超时功能的研究和设计 学生:詹步康 指导教师:张武 (安徽农业大学 信息与计算机学院 合肥 230036) 摘要:摘要:本课程设计运用了所学的java语言基础知识,面向对象程序设计的基本思想、方 法与技术,网络通信编程技术等开发了简单应用功能-基于java的农业物联网中间件的 判断dtu超时功能。详细地介绍了本课程设计运用了所学的java语言基础

4、知识,面向对象 程序设计的基本思想、方法与技术,网络通信编程技术等开发了简单应用功能-基于 java的农业物联网中间件的判断dtu超时功能。详细地介绍了基于java的农业物联网中间 件的判断dtu超时功能的设计方法,给出了该功能的java程序设计,该程序可直接用作服 务器端程序,接受并处理数据。服务器端数据中心与客户端dtu通过socket建立连接,利 用输入输出流透明传送数据。服务器端程序主要包括节点类、工作线程类(接受并处理 数据所用)、轮询类等,以及用于存储节点的哈希表、同步锁和支持多客户端的线程; 客户端程序主要有计时器类(每隔一定时间向服务器端发送一数据)。 关键词:关键词:dtu;

5、超时;轮询 java-based research of internet of things of agriculture middleware research and design of judgment of dtu timeout function student: zhan bu kang teachers: zhang wu (school of information client program mainly include the timer class (sending a data at regular intervals to the server). keyword

6、s:dtu;timeout ;polling 目录目录 1 引言引言.3 2.课题的总体目标与主要研究内容课题的总体目标与主要研究内容.4 2.1 课题的总体目标4 2.2 研究的主要内容4 2.2.1 下面就本课题所做的工作的主要内容4 2.2.2 本论文的章节安排4 3 总体设计总体设计.4 3.1 需求分析与设计思想:4 3.1.1 对判断dtu超时功能的需求分析4 3.1.2 对判断dtu超时功能的设计思想4 3.2 设计时用到的重要的技术或数据结构5 3.2.1同步锁5 3.2.2哈希表7 3.2.3线程8 4 程序的详细设计程序的详细设计.10 4.1 程序流程图10 4.2 数据

7、字典11 4.2.1 主类server11 4.2.2启动服务器startserver 12 4.2.3节点类node13 4.2.4工作线程workthread 14 4.2.5 轮询类lookup15 4.2.6客户端类client16 4.2.7工作计时器类mytask16 5 结论:结论:.17 主要参考文献主要参考文献.17 致谢致谢.18 附录附录 1:.18 附录附录 2.31 2.1 运行结果及界面31 2.1.1启动服务器前:31 2.1.2启动服务器但不启动客户端:32 2.1.3启动服务器并启动多个客户端:33 2.1.4 启动服务器并启动多个客户端最后关闭全部客户端:3

8、4 1 引言引言 随着经济社会的不断发展和进步,无线通信技术在人们生活中已变得愈发重要,受 到广泛运用。应用了无线通信技术的 gprs dtu 遍布了人类生活各个领域,被广泛应用于 电力、水利、市政、交通、金融、环境监测、农业等行业领域。尽管应用的行业不同,但应 用的原理是相同的,大都是 dtu 和行业设备相连,然后和后台建立无线的通信连接。在农业监测系 统中,常常需要对众多农业园的 co2 浓度,光照强度,土壤酸碱度等进行实时监测,大部分监测数 据需要实时发送到管理中心的后端服务器进行处理。由于监测点分散,分布范围广,而且大多设置在 环境较恶劣的地区,通过电话线传送数据往往事倍功半。通过 g

9、prs 无线网络进行数据传输,大大提 高水文部门的工作效率,成为农场主、农业部门选择的通信手段之一。 dtu 内嵌了 tcp/ip 协议栈,具有 socket 通讯功能,并提供透明数据传输通道,用户 只需设置一些参数就可实现将嵌入式系统直接与 internet 相连,实现网络的互连互通。 dtu 的主要功能是把远端设备的数据通过无线的方式传送到数据中心,在传送数据之前, dtu 需要与服务器端数据中心建立无线连接。服务器端监控中心的 socket 端口监听程序 负责监听采集终端的连接请求,当监听到连接请求后,建立通信链路,原来负责监听 socket 仍进行监听,通信链路建立后就可任意交换数据了

10、。 当 dtu 长时间没有发送数据到数据中心时,那么数据中心就认为该 dtu 已掉线并断 开与该 dtu 的连接。判断 dtu 超时功能是 dtu 众多功能之一,作用就是帮助数据中心及 时发现那些不传送数据却仍然连接占用大量资源的 dtu,以便让有限的内存资源得到最大 化利用。 图 1 dtu 及其使用示例 2.课题的总体目标与主要研究内容课题的总体目标与主要研究内容 2.1 课题的总体目标课题的总体目标 本课题的目标是,实现个判断 dtu 超时的功能,使用这个功能可以使服务器很大程度上提高自 己管理内存资源的能力。此功能应用于服务器后台上,能比较理想得保证通讯连接的时效性,避免了 那些空占其

11、位,不尽其守的 dtu。 2.2 研究的主要内容研究的主要内容 2.2.1 下面就本课题所做的工作的主要内容 1) 就具体的 dtu 设备进行调研,找出其工作原理,以何种方式发送数据等等。 2) 编写服务器端接受数据的程序,能够从字节流里读取数据。 3) 编写服务器端轮询程序,能够每隔一段时间检查一次各客户端是否掉线。 2.2.2 本论文的章节安排 第 2 章,提出了课题的总体目标与主要研究内容; 第 3 章,对判断 dtu 超时功能的总体设计,对设计有个宏观把握; 第 4 章,对判断 dtu 超时功能的具体设计,详细介绍了设计过程。 第 5 章,针对本文的工作进行了总结以及提出不足之处。 3

12、 总体设计总体设计 3.1 需求分析与设计思想:需求分析与设计思想: 3.1.1 对判断 dtu 超时功能的需求分析 在互联网日益发展的今天,dtu 的使用也越来越广泛,为各行业之间的信息、产业融 合提供了帮助。可往往运用 dtu 的过程中难免会遇到令人不快的情况使得 dtu 无法正常 向服务器发送数据,这些情况常见有:突然断电、dtu 本身电路故障、信号太弱、等等。 服务器与众多 dtu 通讯时,可能某一 dtu 故障而无法向服务器发送数据,此时服务器还在默默等待 该 dtu 传送的信息。大家都知道服务器根本接受不到该 dtu 发来的数据,但是此时服务器还与该 dtu 连接着,占着服务器宝贵

13、的内存资源双方却不能正常通讯,显然这浪费资源,要是众多 dtu 都 是这样尸位素餐的话,总有某一刻服务器也被“卡死了” 。所以为了消除这种隐患,迫切需要一种功能 能够准确查出那些尸位素餐的 dtu,然后把它们“踢下线”以释放资源。 3.1.2 对判断 dtu 超时功能的设计思想 启动服务器,打开了轮询程序并启动了监听程序,等候客户端的连接。若有客户端发来连接 请求时,服务器就专门为这个客户端启动一个线程来接受并处理该客户端发来的数据;另外服务器会 创建个节点来代表该客户端,并将该节点存在哈希表中。节点里封装有客户端的 ip 地址、连接端口号、 向服务器发送的数据、该节点在哈希表中存放的位置(即

14、:键值)以及最后一次与服务器通讯时的时 间(客户端向服务器发送一次数据,该时间即更新一次) 。 轮询程序启动以后,会每隔一段时间轮询 一次哈希表,对里面存储的客户端节点中的时间进行检查,若其大于指定值则默认该客户端节点已故 障,将与其断开连接。 3.2 设计时用到的重要的技术或数据结构设计时用到的重要的技术或数据结构 3.2.1 同步锁 当我们用多线程访问或修改同一共享资源时,可能会引起线程间的冲突,因此引入 线程同步机制,来让先到的线程率先访问或修改该共享资源而在这一线程对共享资源的 访问或修改还没有结束之前,任何要访问或修改该共享资源的线程都必须等待,这样就 很好得解决了线程间的并发问题。

15、 本设计中轮询机制的代码在访问或删除哈希表中的客 户端节点时,必须考虑到此时可能有新的客户端向服务器端发出连接请求但是轮询尚未 结束不能将新来的节点插入哈希表,所以要将轮询代码与向哈希表插入节点的代码同步 起来。 同步分为 同步方法 和 同步块 两种方式。 3.2.1.1 synchronized 加在方法上, (同步方法,锁定类实例) java 代码 public class demo1 public synchronized void m1() /. public void m2() /. synchronized(this) /. /. 这两种写法的效果是一样的,锁定的都是类实例。如果有

16、两个 类实例: de1 = new demo1(),de2 = new demo1(),另外有两个线程: thread1,thread2,都调用了 de1 对象,那么,在同一时间,如果 thread1 调用了 de1.m1(),则 thread2 在该时间内 不能访问 de1.m1() 和 de1.m2(); 因为 thread1 把 de1 这个对象的锁使用了,所以无法 分给其它线程使用。但是,如果 thread1 调用 de1.m1(), thread2 调用 de2.m1(), 则可 以同时进行,因为它们调用的是不同的 demo1 类对象实例。 3.2.1.1 synchronized

17、加在变量上, (同步块,锁定类实例) java 代码 public class demo2 object a = new object(); object b = new object(); public void m1() /. synchronized(a) /. /. public void m2() /. synchronized(b) /. /. 这种情况下,是实现代码块锁定,锁定的对象是变量 a 或 b; (注意:a 、b 都是 非 static 的)如果有一个 类实例: do = new demo2(),另外有两个线程: thread1,thread2,都调用了 do 对象,那么

18、,在同一时间,如果 thread1 调用了 do.m1(),则 thread2 在该时间内可以访问 do.m2();但不能访问 do.m1() 的同步块, 因 为 a 被 thread1 锁定了。 若此代码里 a、b 变量用 static 修饰,其锁定的对象都是类 demo2,而不是类的实 例,即在多线程中,其共享的资源是属于类的,而不是属于类对象的。在这种情况下, 如果 thread1 访问了这 2 个方法中的任何一个, 在同一时间内其它任何线程都不能访问 这 2 个方法。 3.2.2 哈希表 3.2.2.1 哈希表的定义及其构造方法 哈希表是一种重要的存储方式,也是一种常见的检索方法,是基

19、于哈希表的 map 接 口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。除了非 同步和允许使用 null 之外,hashmap 类与 hashtable 大致相同。其基本思想是将关系 码的值作为自变量,通过一定的函数关系计算出对应的函数值,把这个数值解释为结点 的存储地址,将结点存入计算得到存储地址所对应的存储单元。检索时采用检索关键码 的方法寻找对应的节点。现在哈希表有一套完整的算法来进行插入、删除和解决冲突。 在 java 中哈希表用于存储对象,实现快速检索。 java.util.hashmapjava.util.hashmap提供了若干种方法让用户很方便

20、地使用哈希表,而不需要 考虑其真正如何工作的。 哈希表类中提供了三种构造方法,分别是: public hashmap () public hashmap (int initialcapacity) public hashmap (int initialcapacity,float loadfactor) public hashmap(map m) 参数 initialcapacity 是 hashmap 的初始容量,它的值应大于 0。loadfactor 又称 装载因子,是一个 0.0 到 0.1 之间的 float 型的浮点数。它是一个百分比,表明了哈希 表何时需要扩充,例如,有一哈希表,容

21、量为 100,而装载因子为 0.9,那么当哈希表 90%的 容量已被使用时,此哈希表会自动扩充成一个更大的哈希表。如果用户不赋这些参数, 系统会自动进行处理,而不需要用户操心。 3.2.2.2 hashmap 提供了基本的插入、检索等方法。 插入 public v put(k key,v value) 在此映射中关联指定值与指定键。如果该映射以前包含了一个该键的映射关系,则旧值 被替换。 检索 public boolean containsvalue(object value) 如果此映射将一个或多个键映射到指定值,则返回 true。 public set keyset() 返回此映射中所包含

22、的键的 set 视图。该 set 受映射的支持,所以对映射的更改将反 映在该 set 中,反之亦然。如果在对 set 进行迭代的同时修改了映射(通过迭代器自 己的 remove 操作除外),则迭代结果是不确定的。该 set 支持元素的移除,通过 iterator.remove、set.remove、removeall、retainall 和 clear 操作可从该映射中移 除相应的映射关系。它不支持 add 或 addall 操作。 public collection values() 返回此映射所包含的值的 collection 视图。该 collection 受映射的支持,所以对映 射的更

23、改将反映在该 collection 中,反之亦然。如果在对 collection 进行迭代的同 时修改了映射(通过迭代器自己的 remove 操作除外),则迭代结果是不确定的。该 collection 支持元素的移除,通过 iterator.remove、collection.remove、removeall、retainall 和 clear 操作可从该 映射中移除相应的映射关系。它不支持 add 或 addall 操作。 public setmap.entry entryset() 返回此映射所包含的映射关系的 set 视图。 该 set 受映射支持,所以对映射的更改将 反映在此 set

24、中,反之亦然。如果在对 set 进行迭代的同时修改了映射(通过迭代器 自己的 remove 操作,或者通过在该迭代器返回的映射项上执行 setvalue 操作除外), 则迭代结果是不确定的。该 set 支持元素的移除,通过 iterator.remove、set.remove、removeall、retainall 和 clear 操作可从该映射中移 除相应的映射关系。它不支持 add 或 addall 操作。 删除 public v remove(object key) 从此映射中移除指定键的映射关系(如果存在)。 public void clear() 从此映射中移除所有映射关系。此调用返

25、回后,映射将为空。 3.2.3 线程 3.2.3.1 线程的设计 在 java 中,创建线程的方法有两种:一种是通过创建 thread 类的子类来实现;另 一种是通过实现 runnable 接口的类来实现。这两种创建线程方法并没有本质上的区别, 但是由于 java 不允许多重继承,所以当一个类要继承另一个非 thread 类而实现多线程 的话,只能通过实现 runnable 接口的方式来实现。 3.2.3.2 通过 thread 类实现 定义一个线程类,他继承类 thread 并重写其中的 run()方法。这时在初始化这个类的 实例时,目标对象 target 可以为 null,表示这个实例本身

26、具有线程体。由于 java 只 支持单继承,用这种方法定义的类不能再继承其他类。1 thread 类定义的用来帮助管理线程的方法主要包括以下内容 : void run()方法:线程的入口点,运行线程中的代码。 void start()方法:通过调用运行方法来启动线程,使之由出生状态转 入就绪状态。 void sleep(long milis):在一段时间内挂起线程,令线程睡眠,在此期 间,线程不消耗 cpu 资源;以毫秒为单位。 void interrupt():中断线程。 boolean isalive():判定线程是否仍在在运行,出于活动状态。 void stname(string thr

27、eadname):改变线程的名字。 string getname():获取由 setname()方法实质的线程名字的字符串。 yield():将 cpu 控制权主动移交到下一个可运行的线程。 setpriority(int p):设置线程优先级。 getpriority():获得线程优先级。 join():等待一个线程终止。 3.2.3.3 实现 runnable 接口 创建线程的最简单的方法就是创建一个实现 runnable 接口的类。然后根据工作需要 重新设计线程的 run 方法;再建立该类的对象。runnable 抽象了一个执行代码单元。你 可以通过实现 runnable 接口的方法创建

28、每一个对象的线程。为实现 runnable 接口,一 个类仅需实现一个 run()的简单方法。 3.2.3.4 线程的生命周期 每个线程的生命周期一共包括 5 种状态:出生,就绪,运行,阻塞和死亡。线程从 出生到死亡的过程称为线程的生命周期。通过特定的操作可以进行状态间的转换。 3.2.3.5 出生 当用关键字 new 和 thread 类或其子类建立了一个线程对象后,该线程就处于出生状 态。 thread 线程名=new thread() ; 处于新建状态的线程只是一个空闲的线程对象,系统并没有为他分配资源。在调用 start 方法之前,线程就一直处于出生状态。 3.2.3.6 就绪 在调用

29、了 start 方法之后,线程就进入就绪状态,即被加入到处于就绪状态的线程序 列中,在等待 cpu 时间片。线程名.start() ; 3.2.3.7 运行 当处于线程序列中的线程获得 cpu 时间片的时候,该线程就会自动调用其 run 方法,进入运行状态。 4 程序的详细设计程序的详细设计 4.1 程序流程图程序流程图 判断 dtu 超时功能程序共有 8 个 java 源文件。重要之间的关系如下图; 图 2 类之间的关系 server.java 该文件是 java application 程序,负责创建程序的主窗口。该类含有 init 方法,程 序从该类开始执行。 startserver.j

30、ava 该文件生成的类负责将服务器端套接字绑定端口号和 ip 地址,启动服务器,建立监 听系统。当有客户端发来连接请求时即建立连接,然后启动工作线程。 node.java 该文件生成的类的对象代表一个客户端节点,节点里存储着客户端发向服务器端的信 息、客户端最后一次与服务器端通讯的时间、客户端的 ip 地址和端口号、客户端套接字 以及该节点在哈希表中所对应的键值。 workthread.java 该文件生成的类负责创建工作线程。接受并处理客户端发向服务器端的数据。每接受 一次数据,都要根据该数据对这个工作线程对应的客户端节点里的信息进行更新。 lookup.java 该文件生成的类负责对哈希表

31、 1 中各客户端节点最后一次与服务器端通讯的时间进 行检查。 使用迭代器遍历哈希表 1,查出超时的客户端节点便将其键值放入哈希表 2, 等轮询一周结束,用迭代器遍历哈希表 2 将哈希表 1 中超时的客户端节点踢下线并将其 从哈希 表 1 中删除。 client.java(测试类) 该文件生成的类负责向服务器端发送数据。首先在其主函数中通过构造函数 socket(inetaddress address, int port)绑定服务器端的地址和端口号,然后启动 定时器。 mytask.java(测试类) 该文件主要负责创建一个定时器,每隔一定时间向服务器端发送数据。 4.2 数据字典数据字典 4.

32、2.1 主类 server 4.2.1.1 成员变量(见表 1) 表 1 server 类的主要成员变量(属性) 变量名变量名变量类型变量类型可见性可见性成员变量描述成员变量描述 tatextarea 文本区域 lb1label 标签 lb2label 标签 tf1textfield 文本框 tf2textfield 文本框 btnbutton 按钮 4.2.1.2 方法(见表 2) 表 2 server 类的主要方法 名称名称功能功能返回值返回值备注备注 server 创建程序主窗口构造方法 actionperformed 处理 actionevent 事 件 接口方法 init 程序开始运

33、行applet 程序从 此处开始运行 4.2.2 启动服务器 startserver 4.2.2.1 成员变量(见表 3) 表 3 startserver 类的主要成员变量 变量名变量名变量类型变量类型可见性可见性成员变量描述成员变量描述 hmhashmap 哈希表 num_threadint 当前工作线程数 ssserversocket 服务器套接字 addrinetaddress 服务器 ip 地址 的 inetaddress 对象 ipstring ip 地址字符串 形式 portint 端口号 4.2.2.2 方法(见表 4) 表 4 startserver 类主要方法 名称名称功能功

34、能返回值返回值备注备注 startserver 初始化 ip 地址和端口 号 构造方法 run 线程的主部;建立服务 器端的监听机制,收到 连接请求即建立连接并 启动工作线程 线程的 run() bind_port 使服务器端绑定固定的 ip 地址和监听端口号 4.2.3 节点类 node 4.2.3.1 成员变量(见表 5) 表 5 node 类的主要成员变量 变量名变量名变量类型变量类型可见性可见性成员变量描成员变量描 述述 datastring 记录客户端向 服务器端发的 数据 timelong 收到最后一条 信息时的时刻 ipstring 客户端的 ip 地址 portint 客户端的

35、端口 号 socketsocket 客户端套接字 keychar 节点存入哈希 表时的键值 4.2.3.2 方法 (见表 6) 表 6 node 类的主要方法 名称名称功能功能返回值返回值备注备注 node 创建客户端节点构造方法 getip 获取节点内存储的客户端 ip 地址 ip 是 string 类 型 setip 设置 ip 地址值 getport 获取节点内存储的客户端 端口号 setport 设置客户端端口号 gettime 获取节点内存储的服务器 与客户端最后一次通讯的 时间 settime 更新某节点内存储的服务 器与客户端最后一次通讯 的时刻 getdata 获取节点内存储的

36、客户端 发来的信息 setdata 更新节点内存储的客户端 发来的信息 getsocket 获取节点内存储的客户端 套 setsocket 更新节点内存储的客户端 套接字 getkey 获取哈希表内存储的该节 点对应的键值 4.2.4 工作线程 workthread 4.2.4.1 成员变量(见表 7) 表 7 workthread 类的主要成员变量 变量名变量名变量类型变量类型可见性可见性成员变量描述成员变量描述 chchar 客户端发的心跳 包的字符串信息 的第九位字符 datastring 客户端发来的信 息 bbyte 服务器端从输入 流读取数据放入 字节数组 b 中 flagbool

37、ean 用于标记是否同 一个客户端向服 务器端发信息 nodenode node 类的实例, 即客户端节点 socketsocket 客户端套接字 hashlockobject 同步锁 4.2.4.2 方法(见表 8) 表 8 workthread 类的主要方法 名称名称功能功能返回值返回值备注备注 workthread 初始化客户端套接字 socket构造方法 run 工作线程主部,接受并处理客户端发向 服务器端的信息 4.2.5 轮询类 lookup 4.2.5.1 成员变量(见表 9) 表 9 lookup 类的主要成员变量 变量名变量名变量类型变量类型可见性可见性成员变量描述成员变量描

38、述 now_datelong 开始轮询时的时 间 last_datelong 客户端最后一次 与服务器端通讯 时的时间 nodenode 轮询期间,代表 所检查时间的当 前节点 node2node 轮询后,代表所 检查出超时的节 点 hm2hashmap 存储轮询期间检 查出超时的节点 ititerator 哈希表 1 的迭代 器 it2iterator 哈希表 2 的迭代 器 4.2.5.2 方法(见表 10) 表 10 lookup 类的主要方法 名称名称功能功能返回值返回值备注备注 run 线程的 run 方法 chaxun 轮询哈希表检查是否 有超时的客户端节点 delete 把超时的

39、客户端踢下 线并从哈希表中删除 4.2.6 客户端类 client 4.2.6.1 成员变量(见表 11) 表 11 client 类的主要成员变量 变量名变量名变量类型变量类型成员变量描述成员变量描述 socketsocket 客户端套接字 4.2.6.2 方法(见表 12) 表 12 client 类的主要方法 名称名称功能功能返回值返回值备注备注 main 将套接字绑定服务器 端的 ip 地址和端口 号 4.2.7 工作计时器类 mytask 4.2.7.1 成员变量(见表 13) 表 13 mytask 类的主要成员变量 变量名变量名变量类型变量类型可见性可见性变量描述变量描述 dat

40、astring 客户端要发送的 信息 socketsocket 客户端套接字 outdataoutputstrea m 输出流 4.2.7.2 方法(见表 14) 表 14 mytask 类的主要方法 名称名称功能功能返回值返回值备注备注 mytask 初始化 socket构造方法 run 向输出流写数据 closesocket 关闭输出流和套接字 释放资源 接口方 法 5 结论:结论: 本文对 gprs 判断 dtu 超时功能的开发过程进行了详细的分析说明。本文遵循了 “从当前应用的存在的问题提出开发需求形成系统架构具体功能实现”的流程 来实现功能,此功能已经通过实际测试,运行良好,并得到应

41、用。 本课题的创新点:判断 gprs 判断 dtu 超时功能的设计,能够使服务器更好得管理 自己的内存资源,并提高了通信稳定性,具有很高的实用价值和经济价值。文章中采用 哈希表存储 dtu 节点,大大提高了服务器管理各 dtu 及自己资源的效率,并使用了同步 锁,在这多线程程序中很好得避免多条线程同时访问或修改哈希表等共享资源而产生的 冲突。 本设计的不足:由于无法明确 dtu 的生产厂家所设计使用通信协议,故无法获取 dtu 在与 dsc 建立连接后发来的注册包,因此服务器不好对各个与之建立连接的 dtu 做标 识。无奈之下,通过设置 dtu 的心跳包内容,使之包含其对应的 dtu 的身份信

42、息,从而 让服务器提取并作为发送该心跳包的 dtu 的身份标识。 主要参考文献主要参考文献 1 印旻,王行言.java 语言与面向对象程序设计(第二版).北京:清华大学出版社,2007,11. 2 黄晓东.java 课程设计案例精编m.北京:中国水利水电出版社,2004,5. 3 陆迟.java 语言程序设计(第一版) m.北京:电子工业出版社,2002 4 张广彬.java 课程设计案例精编(第二版) m.北京:清华大学出版社,2007 致谢致谢 随着本科生活的临近尾声,五个月的毕业设计也将结束,我也顺利的完成设计 gprs 判断 dtu 超时的功能。 在开发设计的过程中,指导老师张武本着认

43、真负责的态度、以严谨求真的作风来 要求我们每一位学生,从选题到研发到实现,指导老师给予了我正确的指导和极大的帮 助,使得我在设计当中少走了很多弯路。还有学长-胡鸿超,在编程设计过程,给予了 我极大的帮助,从理论知识到实际操作都给我很大的支持,让我从刚开始接到课题时一无 所知到现在成功完成毕业设计,我感到非常欣慰!在顺利完成毕业设计的同时更让我学到了许 多知识,对原有的理论知识能够很好的与实际结合起来运用,也大大的提高了我的编程 能力,这使得我对以后的工作充满了信心。 在此我由衷的向我的指导老师、学长还有那些一起走过来的同学朋友们再次地说 一声谢谢!今后我会以此次的毕业设计为起点迈向更远的未来。

44、 附录附录 1: node.javanode.java import .socket; public class node private string data; private long time; private string ip; private int port; private socket socket; private char key; node() /构造函数 node(int port) this.port=port; public string getip() /处理 ip 地址 return ip; public void setip(string ip) this

45、.ip = ip; public int getport() /处理端口号 return port; public void setport(int port) this.port=port; public long gettime() /处理时间 return time; public void settime(long time) this.time=time; public string getdata() /处理数据 return data; public void setdata(string data) this.data=data; public void setsocket(s

46、ocket socket) /处理 socket 接口 this.socket=socket; public socket getsocket() return socket; public char getkey() /处理键值 return key; public void setkey(char key) this.key = key; server.javaserver.java import java.applet.applet; import java.awt.button; import java.awt.color; import java.awt.flowlayout; im

47、port java.awt.label; import java.awt.textarea; import java.awt.textfield; import java.awt.event.actionevent; import java.awt.event.actionlistener; import java.awt.event.focusevent; import java.awt.event.focuslistener; public class server extends applet static textarea ta; label lb1,lb2; textfield tf

48、1,tf2; button btn; public void init() ta = new textarea(25,45); lb1=new label(请输入 ip 地址:); lb2=new label(请输入端口号:); tf1= new textfield(0.0.0.0,25); tf2 = new textfield(0,20); btn=new button(启动); add(lb1); add(tf1); add(lb2); add(tf2); add(btn); add(ta); setlayout(new flowlayout(); resize(400,500); se

49、tbackground(color.yellow); tf1.addfocuslistener(new handlefocus(); tf2.addfocuslistener(new handlefocus(); btn.addactionlistener(new handleact(); class handleact implements actionlistener string ipp=null; int portt = 0; public void actionperformed(actionevent e) ipp=tf1.gettext(); portt=integer.pars

50、eint(tf2.gettext(); new thread(new startserver(ipp,portt).start(); lookup lk=new lookup(); lk.start(); class handlefocus implements focuslistener string str; public void focusgained(focusevent e) public void focuslost(focusevent e) if(e.getsource()=tf1) str=tf1.gettext(); if(str.equals(0.0.0.0)|str.

51、length()7) tf1.requestfocus(); tf1.settext(0.0.0.0 ); else str=tf2.gettext(); if(integer.parseint(str)=0) tf2.requestfocus(); tf2.settext(0); startserver.javastartserver.java import java.io.ioexception; import .inetaddress; import .inetsocketaddress; import .serversocket; import .socket; import java

52、.util.hashmap; class startserver implements runnable static hashmap hm = new hashmap(); static int num_thread = 0;/ 当前的连接数(工作线程数) private serversocket ss; private static inetaddress addr; string ip; int port; startserver(string ip,int port) this.ip=ip; this.port=port; public void run() try addr =ine

53、taddress.getbyname(ip) ; catch(exception e) e.printstacktrace(); ss = bind_port(port);/ 绑定端口和 ip 地址 if (ss = null) server.ta.append(创建 serversocket 失败!n); return; while (true) socket socket = null; try socket = ss.accept(); workthread h=new workthread(socket); thread workthread = new thread(h); work

54、thread.start(); catch (ioexception e) e.printstacktrace(); /* * 创建一个 serversocket 来侦听用户心跳包请求 * */ public serversocket bind_port(int port) serversocket serversocket = null; try serversocket = new serversocket(); if (!serversocket.getreuseaddress() serversocket.setreuseaddress(true); serversocket.bind

55、(new inetsocketaddress(addr, port); server.ta.append(启动服务器。 。 。 。 。 。 。n); server.ta.append(“开始在 + serversocket.getlocalsocketaddress()+ 上侦听用户的心跳包请求!n); catch (ioexception e) server.ta.append(端口 + port + 已经被占用!n); if (serversocket != null) if (!serversocket.isclosed() try serversocket.close(); catch

56、 (ioexception e1) e1.printstacktrace(); return serversocket; workthread.javaworkthread.java import java.io.datainputstream; import java.io.ioexception; import .socket; import java.sql.connection; import java.sql.drivermanager; import java.sql.sqlexception; import java.sql.statement; import java.text

57、.simpledateformat; import java.util.date; class workthread implements runnable char ch; string data; /string u1,u2,address; byte b; boolean flag=true; datainputstream in; node node = new node(); private socket socket; static object hashlock = new object();/锁 /* * 构造函数,从调用者那里取得 socket * */ public wor

58、kthread(socket socket) this.socket = socket; public void run() try server.ta.append(n 用户已连接:+ socket.getinetaddress() + : + socket.getport()+n); in = new datainputstream(socket.getinputstream(); while (true) b=new byte30; in.read(b); data = new string(b); if(flag) ch=data.charat(9); if(startserver.h

59、m.containskey(ch) startserver.hm.remove(ch); node.setkey(ch); synchronized (hashlock) startserver.hm.put(ch, node); flag=false; node.settime(new date().gettime(); if(data.substring(0, 11).equals(11300000000) node.setport(socket.getport(); node.setip(socket.getinetaddress().tostring(); node.setsocket(socket); /* address=data.substring(0, 12); u1=data.substring(16, 21); u2=data.substring(24, 28); string sql=insert into table_1(address,u1,u2,time) values(+address+,+u1+,+u2+,getdate(); connection conn; try conn = drivermanager.getconnection(dburl,user,password); st

温馨提示

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

评论

0/150

提交评论