




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Java后台服务程序设计在很多大型软件项目中,都有一些极为重要的后台服务程序,它们并不处理具体的系统业务逻辑,但对整个系统资源和服务的协调管理却是不可或缺。本文讨论如何完整地编写一个后台服务管理程序,并通过一个具体的后台服务管理例子来说明这一技术实现的技巧。为什么需要后台服务程序?在许多大型软件项目中,后台服务程序都扮演着极为重要的角色。它们无处不在,例如操作系统的内核程序处理各种对操作系统的内部调用;数据库系统的核心管理进程处理各种对数据库的读写操作和进程、资源的管理;大型ERP软件的内核管理程序要完成各种应用模块的资源、通讯管理等等。它们使系统的各种服务、资源与应用的表示之间形成了一个松耦
2、合关系,这样就极大地增加了软件系统的稳定性和伸缩性。后台服务程序也就是相当于软件系统的管理调度中心,它是软件系统的中央处理器,是保证应用高效运行的内核程序。在不同的软件系统中,由于软件的复杂程度和功能的不同使得各种软件系统的后台服务程序都有存在较大的差异。但是后台服务程序还是有很多共同的特点,一个基本的后台服务程序大概可以由四个部分构成:通用服务器框架、服务与监听、服务控制、服务器实现。下面我们就使用具体的代码来实现一个基本的后台服务器程序。通用服务器框架在开发后台服务程序中,我们首先实现一个通用服务器框架类,它能在多个端口提供多线程的服务(由多个Service对象定义),并且能够在系统运行时
3、动态地调用和实例化Service类并加载新的服务或卸除已加载的服务。清单 1显示了如何编制一个通用服务器框架类文件。【清单 1:通用服务器框架类文件Server.java】import java.util.*;import java.io.*;import .*;public class Server protected Map services; Set connections; int maxConnections; int freeConn; ThreadGroup threadGroup; private int currentConn; private PrintWriter log
4、 = new PrintWriter(System.out, true); public boolean connected = false; public Properties proPort, proNum; public synchronized void setControlFlag() connected = true; public synchronized void removeControlFlag() connected = false; public void setProperty(Properties proPort, Properties proNum) this.p
5、roPort = proPort; Num = proNum; public Server(int maxConn) this.maxConnections = maxConn; this.freeConn=maxConnections; this.threadGroup = new ThreadGroup(Server.class.getName(); currentConn = 0; this.services = new HashMap(); this.connections = new HashSet(maxConnections); public synchroniz
6、ed void addService(Service service,int port, int maxConn) throws IOException String servicename = service.getClass().getName(); Integer key = new Integer(port); if (services.get(key) != null) throw new IllegalArgumentException("端口:" + port + " 已经被占用!"); if (getfreeConnections(max
7、Conn)>=0) Listener listener = new Listener(this, port, service, maxConn); services.put(key,listener); log.println("启动" + servicename + "服务在" + port +"端口上"); listener.start(); else System.err.println("系统并发连接限制已经达到最大值!"); System.err.println("服务" + s
8、ervicename + " 启动失败!"); public synchronized void addService(Service service,int port) throws IOException this.addService(service,port,10); public synchronized boolean removeService(int port) Integer key = new Integer(port); int maxConn =10; final Listener listener = (Listener) services.get
9、(key); if (listener = null) log.println("Service " + " isn't started on port " + port); return false; services.remove(key); listener.pleaseStop(); freeConn+=listener.maxConn; log.println("Close " + listener.service + " on port " + port); return true; publi
10、c synchronized void displayStatus(PrintWriter out) Iterator keys = services.keySet().iterator(); while (keys.hasNext() Integer port = (Integer) keys.next(); Listener listener = (Listener) services.get(port); out.println("服务" + listener.service + "运行" + port + "n"); out.
11、println("连接限制为" + maxConnections); Iterator conns = connections.iterator(); while (conns.hasNext() Socket s = (Socket) conns.next(); int sport = s.getLocalPort(); Listener listen = (Listener) services.get(new Integer(sport); String servicename = listen.service; out.println(servicename + &q
12、uot;响应请求在" + s.getInetAddress().getHostAddress() + "的" + sport + "端口上"); out.println("当前连接数为" + currentConn); out.println("当前系统空闲连接数为" + freeConn); private synchronized int getfreeConnections(int maxConn) int num = -1; if (freeConn >= maxConn) freeConn
13、-=maxConn; num = freeConn; return num; public synchronized int getConnections() return currentConn; public synchronized int addConnections(Socket s) connections.add(s); return currentConn+; public synchronized int removeConnections(Socket s) connections.remove(s); try s.close(); catch (Exception e)
14、System.out.println(e.getMessage(); return currentConn-; public synchronized int getConnections(int connections) int num = 0; if (num=freeConn-connections) >= 0) freeConn = num; else num = -1; return num; private synchronized int getFreeConn() return freeConn; 如上所述可知,服务器框架类Server主要是通过端口到监听器影射的散列表s
15、ervices来管理服务对象,Server类的几个主要方法说明如下:· addService方法:此方法能够在特定的端口上创建新的服务,即在指定端口上运行指定的Service对象。· removeService方法:此方法使服务器停止指定端口上的服务,并不终止连接,仅使服务器停止接受新的连接。· displayStatus方法:此方法用于打印指定流上服务器的状态信息。服务与监听 每个服务都对应着一个监听对象,监听指定端口的连接并在获得连接请求时调用addConnection(Socket s, Service service)方法来取得(释放)一个连接。清单 2显
16、示了如何编制一个监听类文件。 【清单 2:Listener.java的一个简单实现】import java.util.*;import java.io.*;import .*;public class Listener extends Thread private ServerSocket listener; private int port; String service; Set connections; private Service runService; private boolean stop_flag = false; int maxConn; private PrintWrit
17、er log = new PrintWriter(System.err, true); private ThreadGroup group; private int currentConnections = 0; Server server; Socket client = null; public Listener(Server server, int port, Service service, int maxConn, boolean bl) throws IOException this.server = server; this.port = port; this.service =
18、 service.getClass().getName(); this.maxConn = maxConn; this.group = server.threadGroup; this.connections = server.connections; listener = new ServerSocket(this.port); if (bl = false) listener.setSoTimeout(600000); this.runService = service; if (!stop_flag) for (int i=0;i<this.maxConn;i+) Connecti
19、onHandler currentThread = new ConnectionHandler(server,logStream); new Thread(this.group, currentThread, this.service+this.port+i).start(); this.logStream.realLog("向线程组" + group.toString() + "添加一个线程" + this.service+this.port+i); else throw new IllegalArgumentException("系统并发连
20、接限制已经超过最大值!!"); public Listener(Server server, int port, Service service, int maxConn) throws IOException this(server, port, service, maxConn, false); public void pleaseStop() this.stop_flag = true; try listener.close(); catch (Exception e) errupt(); public void run() while(!stop_flag)
21、try client = listener.accept(); addConnection(client,runService); catch (Exception e) try client.close(); catch (IOException e) private synchronized void addConnection(Socket s, Service service) ConnectionHandler.requestToHandler(s, service); 在实际处理过程中,Listener对象通过在指定端口上与指定服务的绑定实现监听过程,主要的几个方法说明如下:
22、183; pleaseStop:以礼貌的方法停止接受连接。 · addConnection:把指定要处理的服务放到线程池中,以等待空闲的线程处理服务。监听对象通过传递一个Service对象并唤醒它的serve()方法才真正提供了服务。下面我们就来实现一个具体的服务:· 服务接口Service只有一个抽象方法serve(InputStream in, OutputStream out),它所有服务实现所必须重写的一个方法,Listing 3显示了一个Service接口的定义。 【清单 3:定义一个Service接口】import java.io.*;import .*;pub
23、lic interface Service public void serve(InputStream in, OutputStream out) throws IOException;· 编写一个简单的显示时间服务类:见清单 4。 【清单 4:一个显示系统当前时间的服务类Timer.java】import java.util.*;import java.text.*;import java.io.*;import .*;public class Timer implements Service public Timer() public void serve(InputStream
24、 in, OutputStream out) throws IOException String timeFormat = "yyyy-MM-dd hh:mm:ss" SimpleDateFormat timeFormatter = new SimpleDateFormat(timeFormat); BufferedReader from_client = new BufferedReader(new InputStreamReader(in); PrintWriter outPrint = new PrintWriter(out); String sDate = time
25、Formatter.format(new Date(); outPrint.println("当前时间是:" + sDate); outPrint.flush(); try from_client.close(); outPrint.close(); catch (Exception e) 通过实现Service接口可以编写很多的服务实现提供各种不同的服务,读者有兴趣也可自己编写一个服务来测试一下。服务控制 服务控制是在服务器运行时动态地操作控制服务器,如系统运行时,动态地装载(卸载)服务,显示服务器的状态信息等等。为了简化基本后台服务系统的复杂程度,我们采用创建一个Con
26、trolService服务实例来在运行时管理服务器。ControlService实现了基于命令的协议,可用密码保护操纵服务器,代码如清单 5所示:【清单 5:服务控制类文件ControlService.java】import java.io.*;import java.util.*;import .*;import dvb.kuanshi.kssms.util.*;import dvb.kuanshi.kssms.server.Server;public class ControlService implements Service Server server; String password
27、; public ControlService(Server server, String password) this.server = server; this.password = password; public void serve(InputStream in, OutputStream out) throws IOException boolean authorized = false; BufferedReader from_client = new BufferedReader(new InputStreamReader(in); PrintWriter to_console
28、 = new PrintWriter(System.out, true); to_console.println("后台管理服务响应请求!n"); PrintWriter to_client = new PrintWriter(out); synchronized (this) if(server.connected) to_client.println("已经有用户连接,本服务仅允许一个连接!n"); to_client.close(); return; else server.setControlFlag(); to_client.println(&
29、quot;Remote Console>"); to_client.flush(); String line; while (line=from_client.readLine()!=null) int len = line.indexOf("Remote Console>"); line = line.substring(len+1,line.length(); String printStr; try StringTokenizer st = new StringTokenizer(line); int count = st.countTokens
30、(); if (!st.hasMoreElements() continue; String first = st.nextToken().toLowerCase(); if (first.equals("password") String pwd = st.nextToken(); if (pwd.equals(this.password) to_client.println("OK"); authorized = true; else to_client.println("密码无效,请重试!n"); else if (first.
31、equals("add") if(!authorized) to_client.println("请登陆!n"); else count-; String servicename; int Port; boolean flag = true; if (count>0) servicename = st.nextToken(); Port = Integer.parseInt(st.nextToken(); server.addService(loadClass(servicename1), Port); to_client.println(&quo
32、t;服务" + servicename + "已经加载n"); flag = false; if (flag) to_client.println("系统不能启动非法服务:" + servicename); else to_client.println("请输入服务名!n"); else if (first.equals("remove") if(!authorized) to_client.println("请登陆!n"); else count-; if (count>0)
33、int port = Integer.parseInt(st.nextToken(); boolean bl = server.removeService(port); if (bl) to_client.println("端口: " + port +"上的服务已经卸载n"); else to_client.println("端口: "+ port +"上无任何服务运行,卸载操作失败!n"); else to_client.println("请输入端口名!n"); else if(first.e
34、quals("status") if(!authorized) to_client.println("请登陆!n"); else server.displayStatus(to_client); else if(first.equals("help") if(!authorized) to_client.println("请登陆!n"); else printHelp(to_client); else if(first.equals("quit") break; else to_client.p
35、rintln("命令不能识别!n"); catch(Exception e) to_client.println("系统后台出错" + e.getMessage() +"n"); printHelp(to_client); to_client.println("Remote Console>"); to_client.flush(); to_client.flush(); authorized = false; server.removeControlFlag(); to_client.close(); fr
36、om_client.close(); private void printHelp(PrintWriter out) out.println("COMMANDS:" + "tpassword <password>n" + "ttadd <servicename> <port>n" + "ttremove <port>n" + "ttstatusn" + "tthelpn" + "ttquitn"); prot
37、ected Service loadClass(String servicename) Service s = null; try Class serviceClass = Class.forName(servicename); s = (Service) serviceClass.newInstance(); catch (Exception e) return s; 服务器实现和运行 服务器实现主要完成服务器的初始化,启动服务控制实例等工作,代码如清单 6所示:【清单 6:runServer.java的一个简单实现】import java.util.*;public class runServer public runServer() public static void main(String args) try int argLen = args.length; System.out.println("正在初始化系统请等待."); System.out.println(""); int maxConn = 30; Server server = new Server(maxConn); System.out.println("#&q
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 林业科研面试题及答案
- 名校考试题型及答案
- 2025-2030中国电子健康记录(EHR)行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030中国电声行业需求趋势及发展策略分析研究报告
- 2025-2030中国生鲜商超行业市场发展分析及竞争格局与投资前景研究报告
- 探索育婴师职业发展路径的学习方法试题及答案
- 渐进式复习2025年税务师考试的策略试题及答案
- 2025-2030中国玻璃纤维增强聚丙烯行业市场发展趋势与前景展望战略研究报告
- 2025-2030中国环保设备行业市场现状供需分析及投资评估规划分析研究报告
- 探索系统架构设计师考试中的多样化应用背景与实践案例试题及答案
- 2024年辅导员岗位素质试题及答案
- 中国资源循环集团有限公司招聘笔试真题2024
- 2024年01月湖南2024岳阳市农商银行系统招考员工笔试历年参考题库附带答案详解
- JGJT46-2024《施工现场临时用电安全技术标准》条文解读
- 自考15040习新时代思想概论高通过率题库
- 预应力混凝土管桩(L21G404)
- DL-T5024-2020电力工程地基处理技术规程
- 2024年郑州职业技术学院单招职业技能测试题库及答案解析
- (高清版)TDT 1013-2013 土地整治项目验收规程
- 个人医保代办委托书
- 驾照体检表完整版本
评论
0/150
提交评论