如何使用Java编写NT服务(二)

王朝java/jsp·作者佚名  2008-05-31
宽屏版  字体: |||超大  

四、为什么要采用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源码结束-------------------*/

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有