服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

如何使用java编写nt服务(二)

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

扫描关注微信公众号