如何使用Java編寫NT服務(wù)_第1頁
如何使用Java編寫NT服務(wù)_第2頁
如何使用Java編寫NT服務(wù)_第3頁
如何使用Java編寫NT服務(wù)_第4頁
如何使用Java編寫NT服務(wù)_第5頁
已閱讀5頁,還剩17頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、 一、NT服務(wù)介紹 所謂NT服務(wù),實際上是一類特殊的應(yīng)用程序所謂NT服務(wù),實際上就是一個可以在系統(tǒng)啟動時自動在一定身份下啟動的伴隨系統(tǒng)長時間存在的進程。象FTP server、HTTP server、脫機打印等都是采用NT服務(wù)的形式提供的。這實際上類似Unix的root daemon進程。NT服務(wù)歸納起來,NT服務(wù)又以下幾個特征: 1、可以自啟動,不需要交互啟動。這對于服務(wù)器來說是一個重要的特征。當然,你可以決定服務(wù)是否自啟動,甚至可以屏蔽某個服務(wù)。 2、NT服務(wù)沒有用戶界面,基本上類似一個DOS 程序,因為NT服務(wù)必須長時間運行,所以不想普通win32進程一樣有自己的界面。但是NT服務(wù)可以同

2、用戶有界面交互,這是一類特殊的服務(wù)進程??梢酝ㄟ^NT的任務(wù)管理器來看到服務(wù)進程。 3、NT服務(wù)通過SCM(Services Control Manager)接口來管理,安裝、啟動、停止、撤除等都需要SCM的接口功能來進行。控制面板的服務(wù)控制器就是利用SCM接口來管理系統(tǒng)中的所有服務(wù)的。實際上,還有一些可以控制服務(wù)的程序或者命令,有net.exe 、服務(wù)器管理器等 、SCM.exe等。 4、這些進程都以一定的身份運行,以方便進行服務(wù)器資源的存取。一般情況下使用域中的LocalSystem賬號運行,此賬號對本機上的大多數(shù)資源(除非特別禁止)有完全的存取權(quán)限,這樣可以保證服務(wù)程序的“強大”。但是,也

3、有些服務(wù)采用特別的賬號運行,你也可以特別設(shè)定一個服務(wù)的帳號。 5、由系統(tǒng)自動以線程方式運行,一般情況下不過多占用系統(tǒng)資源,這同普通的進程有所區(qū)別,如果不采用線程方式,一般進程往往消耗整個CPU資源。一般需要時時存在,又不能過多消耗資源的任務(wù)以服務(wù)來實現(xiàn)最合適。 二、Java編寫服務(wù)的準備 1、作為本地化的實現(xiàn),實現(xiàn)NT服務(wù)的Java程序當然不是100%純Java,單靠標準類庫是無法實現(xiàn)我們的編寫NT服務(wù)的目的,所以MS提供了一套SDK for Java(本文采用的是Microsoft SDK for Java 4.0),提到了如何利用MS提供的擴展類庫和相應(yīng)的工具,實現(xiàn)符合Windows平臺需

4、要的程序。其中包括了實現(xiàn)NT服務(wù)的所需要的類庫API框架以及將Java編譯的class文件組裝成標準的NT服務(wù)程序的工具。SDK的下載路徑可以從/java/查找到。2、安裝完SDK后可以看到在安裝目錄下有jntsvc目錄,此目錄就包含了service.zip文件,它實際上是一個NT services的類庫框架,封裝了一些NT服務(wù)實現(xiàn)細節(jié),使得我們可以按照框架舒服實現(xiàn)我們關(guān)心的細節(jié)。將service.zip展開至開發(fā)機器的系統(tǒng)安裝Service庫到Java擴展庫WinntjavaTrustLib下,如果在其他操作系統(tǒng)下進行開發(fā),參照此系統(tǒng)目錄進行安裝文件。 3、在該目錄下還有一個jntsvc.e

5、xe文件,也就是Java NT Service的意思啦。她可以幫助您實現(xiàn)將按照SDK提供的框架實現(xiàn)的編譯后的class文件組裝成一個標準的NT服務(wù)可執(zhí)行文件。JntSvc幫助我們在已經(jīng)編譯好的.class文件基礎(chǔ)上設(shè)置了所有NT服務(wù)程序必須的特征,是很重要的工具,得到NT服務(wù)取決于如何有效利用她。為了我們能夠方便從任何其他目錄的控制臺窗口調(diào)用她,我們將JntSvc.exe所在的目錄全路徑加入path環(huán)境變量。這可以通過設(shè)置系統(tǒng)屬性的高級屬性頁當中進行環(huán)境變量的設(shè)定。4、按照要求,我們寫好各項代碼,然后編譯編寫Java程序,得到class文件。我們當然不會在Vj Studio中啟動她,因為它目前

6、還沒有可執(zhí)行文件的入口,系統(tǒng)無法啟動她。為了得到NT服務(wù)程序,我們需要在class文件所在目錄的控制臺窗口執(zhí)行一個命令:X:jntsvc *.class /OUT:ECHOSvc.exe /SVCMAIN:EchoSvc /SERVICENAME:ECHOSvc。具體的Jntsvc的參數(shù)我們可以看一看jntsvc -?得到,這里的意思大概是:將當前目錄下的所有class文件組裝成一個NT服務(wù)進程exe文件,文件名為EchoSvc.exe,服務(wù)的啟動入口在echosvc.class中,在注冊表中相應(yīng)的服務(wù)名稱為/Servicename參數(shù)指定的EchoSvc。如果有多個多個NT服務(wù)需要組裝在一個

7、Exe文件中,還可以在 /Out參數(shù)后指定每一個服務(wù)展示名稱。/SVCMAIN參數(shù)指定服務(wù)的入口,所謂入口是指服務(wù)啟動之初是從哪一個類的實例開始的。/SERVICENAME:參數(shù)指定了該服務(wù)將以什么名稱出現(xiàn)。這些參數(shù)都是jntsvc.exe實用工具需要組裝服務(wù)所必須的信息,根據(jù)這些信息將編譯后的.class文件按照win32格式要求得到一個可執(zhí)行文件。 需要注意的是,這個exe文件的運行必須要有JVM存在,她實際上是通過解釋.class來實現(xiàn)服務(wù)提供的。如果需要另外的擴展包,可以通過在/Classpath參數(shù)指定另外的擴展包的位置。所以在安裝Java編寫得到的NT服務(wù)的機器上必須存在JVM。如

8、果是擁有IE5.x那么不用操心這個問題,IE核心組件已經(jīng)包括了JVM;但是如果是IE6版本,則需要到MS的網(wǎng)站上下載JVM。如果您講SDK for Java安裝在服務(wù)器上就更方便了。 5、如果沒有什么錯誤,您將得到一個可執(zhí)行文件echosvc.exe。像大多數(shù)服務(wù)可執(zhí)行文件一樣,它可以將自己安裝到系統(tǒng)中: echosvc.exe install,這一個過程將會往系統(tǒng)注冊表添加一些項目,特別是關(guān)于服務(wù)的項目,SCM也可以列出這個服務(wù)了。我們可以在控制臺下采用DOS NT服務(wù)控制命令Net start/stop來測試服務(wù)是否真像普通服務(wù)一樣可以按照標準方式來控制,當然在服務(wù)管理器當中啟停該服務(wù)更不

9、會有問題。 三、Echo服務(wù)的樣例 當系統(tǒng)載入服務(wù)進程時,入口是在EchoSvc的構(gòu)造函數(shù)中,我們可以看到此構(gòu)造函數(shù)帶有同一般程序的入口main()類似的參數(shù)。 import com.ms.service.* ; public class EchoSvc extends Service static Thread mainSvc=null ; /定義服務(wù)主線程 public EchoSvc (String args) /構(gòu)造此服務(wù) CheckPoint(1000); setRunning(ACCEPT_SHUTDOWN ACCEPT_PAUSE_CONTINUE ACCEPT_STOP); /

10、 該項服務(wù)接受的關(guān)于服務(wù)控制的命令 mainSvc = new Thread(Runnable) new MainSvcThread(); mainSvc.start(); System.out.println( The Echo Service Was Started Successfully!);/紀錄事件,可以通過事件察看器看到 CheckPoint是 Service的同步方法,指示系統(tǒng)正改變服務(wù)的狀態(tài),需要讓系統(tǒng)等待1秒。這里我們啟動的是一個線程,實際上相當于一個進程,她是服務(wù)進程的主線程。在這個線程中我們響應(yīng)SCM對此服務(wù)的控制。大致的表達為: public class MainSv

11、cThread implements Runnable /實現(xiàn)線程控制 public static boolean STOP = false; /由系統(tǒng)來控制的內(nèi)部變量,決定著服務(wù)進程(線程)的啟動、暫停等 public static boolean PAUSE = false; public void run() while (!STOP) while (!PAUSE & !STOP) 。/此處為服務(wù)控制邏輯,下面會充實此處 try Thread.sleep(5000);/休眠5秒后實現(xiàn)暫?;蛘咄V?catch (InterruptedException e) try Thread.slee

12、p(1000); catch (InterruptedException ie) /Run結(jié)束 在服務(wù)邏輯控制當中,我們會具體實現(xiàn)Echo服務(wù)。我們的Echo服務(wù)監(jiān)聽2002端口,接收客戶端任何一行輸入,然后加上“Echo:”后返回。如果客戶端輸入一個quit詞組那么服務(wù)認為這是客戶關(guān)閉此套接字的命令,會自動關(guān)閉當前的套接字連接,停止對當前連接的服務(wù)。具體的實現(xiàn)(EchoThread.java的代碼): public void run() String line; DataInputStream in; PrintWriter out; boolean exitflag=false; try

13、in=new DataInputStream(so.getInputStream() ;/獲取套接字的輸入流 out=new PrintWriter(new DataOutputStream(so.getOutputStream() ; out.println(You have connected to EchoSvc!); /發(fā)送問候 out.flush(); while(line=in.readLine()!=null) /讀取 line=line.trim(); if (line.equalsIgnoreCase(quit) ) out.println(ECHO: + line ); o

14、ut.flush(); return; else out.println(ECHO: + line ); out.flush(); in.close(); out.close(); catch(IOException ioe) Echo服務(wù)主要就是將客戶發(fā)送的字符回顯給客戶,并加上Echo:的前綴,以表明是從服務(wù)器返回的內(nèi)容。如果客戶輸入“quit”那么表示這是要求服務(wù)器停止服務(wù)的表現(xiàn)。 如何調(diào)試NT服務(wù)進程工程。如果直接將此函數(shù)調(diào)用來提供客戶端的ECHO套接字服務(wù),邏輯上是沒有什么錯誤,但是就是無法支持多個用戶同時訪問。為了能夠提供多服務(wù),允許同時又多個用戶連接此服務(wù)器(這種情況在很多網(wǎng)絡(luò)服

15、務(wù)都不可少),我們可以將此邏輯在由MainSvcTread創(chuàng)建的線程中實現(xiàn),而且可以允許多個用戶同時訪問此服務(wù)。具體的表達在MainSvcTread的run函數(shù)中實現(xiàn): while(ListenThreadCount server=li.accept(); /監(jiān)聽 EchoThread p=new EchoThread(server,this);/創(chuàng)建實現(xiàn)該服務(wù)的具體邏輯對象,是一個支持線程的類 Thread t=new Thread(g,(Runnable)p) ; /將當前線程并入線成組 t.start(); /啟動服務(wù)線程 ListenThreadCount+; /修改當前線程數(shù)量 參照

16、上面提到的工具Jntsvc.exe可以幫助你講編譯好的.class文件組裝成exe文件,運行此文并加上-install參數(shù)可以自動幫助您講些好的服務(wù)添加到注冊表中,可以通過服務(wù)管理器或者相當?shù)膶嵱贸绦騺砣缤渌?wù)一樣來進行控制了。撤除服務(wù)采用-uninstall參數(shù)。 本例程采用套接字、多線程實現(xiàn)技術(shù)來解釋實現(xiàn)Java編寫NT服務(wù),實際上類似這樣的很多網(wǎng)絡(luò)方面的服務(wù)都可以按照此規(guī)范實現(xiàn),譬如POP3服務(wù)、FTP服務(wù),甚至WWW服務(wù)等。我們也接觸過像Tomcat、Jrun等Java應(yīng)用服務(wù)器在NT平臺的啟動往往采用NT服務(wù)形式,那么通過此例你也可以嘗試編寫自己的Java服務(wù)應(yīng)用。 最后,如果需

17、要調(diào)試NT服務(wù)的邏輯,可以采用一個變通的辦法。我們在EchoSvc.java中添加一個Main靜態(tài)方法,然后產(chǎn)生一個EchoSvc的實例,這樣就是一個標準的VJ產(chǎn)生的Exe文件,利用Vj的調(diào)試功能我們可以排除隱藏的錯誤。一旦調(diào)通后,我們注釋掉main靜態(tài)方法,編譯后就可以得到一個調(diào)試好的NT服務(wù)。 四、為什么要采用Java編寫NT服務(wù) 比較VC等“原裝”NT服務(wù)開發(fā)方式而言,Java開發(fā)模式可以更快捷,因為幾乎所有得服務(wù)框架通過擴展Services類就可以達到,省下不少復雜的細節(jié)處理。Java語言提供了豐富的類庫,可以為自己使用,可以提高效率,而且編寫的程序結(jié)構(gòu)清晰容易理解,方便以后維護。 J

18、ava提供的異常處理模式,可以讓我們寫好結(jié)構(gòu)良好,更加安全的代碼。試想如果編寫的服務(wù)進程由于采用VC編寫卻忘記對某塊內(nèi)存的釋放,那么服務(wù)啟動后一段時間由于內(nèi)存泄漏造成服務(wù)性能下降,甚至系統(tǒng)崩潰;但是Java本身的語言特性可以使我們不用時刻提防內(nèi)存管理,可以更加關(guān)注服務(wù)邏輯本身,是的實現(xiàn)起來更加有效率。 采用VC如果編寫多線程服務(wù)進程,雖然可以實現(xiàn),但是會相當麻煩。而服務(wù)進程多線程幾乎是每一個性能良好的服務(wù)必備特征,Java語言本身可以提供這方面良好的支持,同時Java自身對網(wǎng)絡(luò)的天然良好支持,使各種網(wǎng)絡(luò)套接字編程容易。 最后,如果不采用其他擴展庫,我們很容易將此服務(wù)邏輯實現(xiàn)在其他操作系統(tǒng)上。一

19、個編寫好的NT服務(wù)程序,可以在去掉對Ms的相關(guān)本地化擴展實現(xiàn)的類引用后,方便移植到其他例如Linux等平臺上,盡可能向Java的“一次編寫、到處可運行”的理想境界靠攏。 五、源碼 /*所附的ZIP文件報含示例的全部工程文件,還有編譯后的NT服務(wù)的可執(zhí)行文件,您可以直接測試此服務(wù)exe文件的安裝、服務(wù)啟停*/ /*EchoSvc.java*/ import com.ms.service.* ; public class EchoSvc extends Service static Thread mainSvc=null ; /定義主線程 public EchoSvc (String args)

20、/構(gòu)造服務(wù) CheckPoint(1000); /服務(wù)是系統(tǒng)的一部分,作為Log紀錄,可以幫助用戶理解系統(tǒng)故障 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源碼結(jié)束-*/ /*MainSvcThread.java*/

21、import java.io.*; import .*; public class MainSvcThread implements Runnable /實現(xiàn)線程控制多線程接口 /將啟動一組線程來監(jiān)聽多個服務(wù)請求 public static boolean STOP = false; /由系統(tǒng)來控制的內(nèi)部變量,決定著服務(wù)進程(線程)的啟動、暫停等 public static boolean PAUSE = false; public int ListenThreadCount=0; /本服務(wù)支持的當前線程數(shù)量 int maxSocket=10; /最大支持的同時連結(jié)數(shù) int SvcPort=

22、2002; /服務(wù)監(jiān)聽的端口 public void run() try while (!STOP) while (!PAUSE & !STOP) /創(chuàng)建監(jiān)聽服務(wù)器 Socket server; ServerSocket li=new ServerSocket(SvcPort); /創(chuàng)建服務(wù)器端套接字 ThreadGroup g=new ThreadGroup(EchoThreads); /創(chuàng)建一組線程 System.out.println(Echo service starting.); /記錄在Log中 while(ListenThreadCount server=li.accept();

23、 /監(jiān)聽 EchoThread p=new EchoThread(server,this); /創(chuàng)建服務(wù)單線程 Thread t=new Thread(g,(Runnable)p) ; /創(chuàng)建新線程 t.start(); /啟動服務(wù)線程 ListenThreadCount+; /當前線程的數(shù)量 try Thread.sleep(5000);/暫停5秒 catch (InterruptedException e) try Thread.sleep(1000); catch (InterruptedException ie) catch (IOException ioe) /Run結(jié)束 /*- MainSvcThread.java源碼結(jié)束-*/ /*EchoThread.java*/ import java.io.*; import .*; /*實現(xiàn)每一個客戶連接到此NT服務(wù)時的服務(wù)器端的線程單元邏輯*/ public class EchoThread implements Runnable /實現(xiàn)線程接口 Sock

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論