四、为什么要采用Java编写NT服务 比较VC等“原装”NT服务开发方式而言,Java开发模式可以更快捷,因为几乎所有得服务框架通过扩展Services类就可以达到,省下不少复杂的细节处理。Java语言提供了丰富的类库,可以为自己使用,可以提高效率,而且编写的程序结构清楚轻易理解,方便以后维护。
Java提供的异常处理模式,可以让我们写好结构良好,更加安全的代码。试想假如编写的服务进程由于采用VC编写却忘记对某块内存的释放,那么服务启动后一段时间由于内存泄漏造成服务性能下降,甚至系统崩溃;但是Java本身的语言特性可以使我们不用时刻提防内存治理,可以更加关注服务逻辑本身,是的实现起来更加有效率。
采用VC假如编写多线程服务进程,虽然可以实现,但是会相当麻烦。而服务进程多线程几乎是每一个性能良好的服务必备特征,Java语言本身可以提供这方面良好的支持,同时Java自身对网络的天然良好支持,使各种网络套接字编程轻易。
最后,假如不采用其他扩展库,我们很轻易将此服务逻辑实现在其他操作系统上。一个编写好的NT服务程序,可以在去掉对Ms的相关本地化扩展实现的类引用后,方便移植到其他例如Linux等平台上,尽可能向Java的“一次编写、到处可运行”的理想境界靠拢。
五、源码 /*所附的ZIP文件报含示例的全部工程文件,还有编译后的NT服务的可执行文件,您可以直接测试此服务exe文件的安装、服务启停*/
/*EchoSvc.java*/ import com.ms.service.* ; public class EchoSvc extends Service { static Thread mainSvc=null ; //定义主线程 public EchoSvc (String[] args) //构造服务 { CheckPoint(1000); //服务是系统的一部分,作为Log纪录,可以帮助用户理解系统故障 setRunning(ACCEPT_SHUTDOWN ACCEPT_PAUSE_CONTINUE ACCEPT_STOP); mainSvc = new Thread((Runnable) new MainSvcThread()); mainSvc.start(); System.out.println( "The Echo Service Was Started SUCcessfully!"); } } /*-------------- EchoSvc.java源码结束-------------------*/
/*MainSvcThread.java*/ import java.io.*; import java.net.*; public class MainSvcThread implements Runnable //实现线程控制多线程接口 { /将启动一组线程来监听多个服务请求 public static boolean STOP = false; //由系统来控制的内部变量,决定着服务进程(线程)的启动、暂停等 public static boolean PAUSE = false; public int ListenThreadCount=0; //本服务支持的当前线程数量 int maxSocket=10; //最大支持的同时连结数 int SvcPort=2002; //服务监听的端口
public void run() { try { while (!STOP) { while (!PAUSE && !STOP) { {//创建监听服务器 Socket server; ServerSocket li=new ServerSocket(SvcPort); //创建服务器端套接字 ThreadGroup g=new ThreadGroup("EchoThreads"); //创建一组线程 System.out.println("Echo service starting..."); //记录在Log中 while(ListenThreadCount<maxSocket) { server=li.accept(); //监听 EchoThread p=new EchoThread(server,this); //创建服务单线程 Thread t=new Thread(g,(Runnable)p) ; //创建新线程 t.start(); //启动服务线程 ListenThreadCount++; //当前线程的数量 } } try { Thread.sleep(5000);//暂停5秒 } catch (InterruptedException e) { } } try { Thread.sleep(1000); } catch (InterruptedException ie) { } } } catch (IOException ioe) {} } //Run结束 } /*-------------- MainSvcThread.java源码结束-------------------*/
/*EchoThread.java*/ import java.io.*; import java.net.*; /*实现每一个客户连接到此NT服务时的服务器端的线程单元逻辑*/ public class EchoThread implements Runnable //实现线程接口 { Socket so=null;//套接字 MainSvcThread p; //一个指向父线程的指针,EchoThread的线程是服务线程的创建的子线程 public void run() { String line; DataInputStream in; //套接字上的输入流 PrintWriter out; //套接字上的输出流,带缓冲 boolean exitflag=false; try { in=new DataInputStream(so.getInputStream()) ;//获取套接字的输入流 out=new PrintWriter(new DataOutputStream(so.getOutputStream())) ; out.println("You have connected to EchoSvc!"); //发送问候 out.flush(); //必须刷新缓冲区内的内容
while((line=in.readLine())!=null && ! exitflag) { line=line.trim(); if (line.equalsIgnoreCase("quit") ) {//假如是退出命令,则关闭当前套接字上的输入输出流 in.close(); out.flush(); out.close(); p.ListenThreadCount --; //主线程的服务线程单元数量控制 return; //退出当前的服务逻辑线程单元 } else { out.println("ECHO:" + line ); out.flush(); } } in.close(); out.close(); p.ListenThreadCount --; } catch(IOException ioe) {} } EchoThread(Socket s,MainSvcThread parent) { so=s; p= parent; } } /*-------------- EchoThread.java源码结束-------------------*/
|