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

下載本文檔

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

文檔簡介

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

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

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

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

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

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

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

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

9、會有問題。 三、Echo服務(wù)的樣例 當(dāng)系統(tǒng)載入服務(wù)進(jìn)程時(shí),入口是在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、 該項(xiàng)服務(wù)接受的關(guān)于服務(wù)控制的命令 mainSvc = new Thread(Runnable) new MainSvcThread(); mainSvc.start(); System.out.println( The Echo Service Was Started Successfully!);/紀(jì)錄事件,可以通過事件察看器看到 CheckPoint是 Service的同步方法,指示系統(tǒng)正改變服務(wù)的狀態(tài),需要讓系統(tǒng)等待1秒。這里我們啟動的是一個(gè)線程,實(shí)際上相當(dāng)于一個(gè)進(jìn)程,她是服務(wù)進(jìn)程的主線程。在這個(gè)線程中我們響應(yīng)SCM對此服務(wù)的控制。大致的表達(dá)為: public class MainSv

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

12、p(1000); catch (InterruptedException ie) /Run結(jié)束 在服務(wù)邏輯控制當(dāng)中,我們會具體實(shí)現(xiàn)Echo服務(wù)。我們的Echo服務(wù)監(jiān)聽2002端口,接收客戶端任何一行輸入,然后加上“Echo:”后返回。如果客戶端輸入一個(gè)quit詞組那么服務(wù)認(rèn)為這是客戶關(guān)閉此套接字的命令,會自動關(guān)閉當(dāng)前的套接字連接,停止對當(dāng)前連接的服務(wù)。具體的實(shí)現(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ù)進(jìn)程工程。如果直接將此函數(shù)調(diào)用來提供客戶端的ECHO套接字服務(wù),邏輯上是沒有什么錯(cuò)誤,但是就是無法支持多個(gè)用戶同時(shí)訪問。為了能夠提供多服務(wù),允許同時(shí)又多個(gè)用戶連接此服務(wù)器(這種情況在很多網(wǎng)絡(luò)服

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

16、上面提到的工具Jntsvc.exe可以幫助你講編譯好的.class文件組裝成exe文件,運(yùn)行此文并加上-install參數(shù)可以自動幫助您講些好的服務(wù)添加到注冊表中,可以通過服務(wù)管理器或者相當(dāng)?shù)膶?shí)用程序來如同其他服務(wù)一樣來進(jìn)行控制了。撤除服務(wù)采用-uninstall參數(shù)。 本例程采用套接字、多線程實(shí)現(xiàn)技術(shù)來解釋實(shí)現(xiàn)Java編寫NT服務(wù),實(shí)際上類似這樣的很多網(wǎng)絡(luò)方面的服務(wù)都可以按照此規(guī)范實(shí)現(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ù)的邏輯,可以采用一個(gè)變通的辦法。我們在EchoSvc.java中添加一個(gè)Main靜態(tài)方法,然后產(chǎn)生一個(gè)EchoSvc的實(shí)例,這樣就是一個(gè)標(biāo)準(zhǔn)的VJ產(chǎn)生的Exe文件,利用Vj的調(diào)試功能我們可以排除隱藏的錯(cuò)誤。一旦調(diào)通后,我們注釋掉main靜態(tài)方法,編譯后就可以得到一個(gè)調(diào)試好的NT服務(wù)。 四、為什么要采用Java編寫NT服務(wù) 比較VC等“原裝”NT服務(wù)開發(fā)方式而言,Java開發(fā)模式可以更快捷,因?yàn)閹缀跛械梅?wù)框架通過擴(kuò)展Services類就可以達(dá)到,省下不少復(fù)雜的細(xì)節(jié)處理。Java語言提供了豐富的類庫,可以為自己使用,可以提高效率,而且編寫的程序結(jié)構(gòu)清晰容易理解,方便以后維護(hù)。 J

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

19、個(gè)編寫好的NT服務(wù)程序,可以在去掉對Ms的相關(guān)本地化擴(kuò)展實(shí)現(xiàn)的類引用后,方便移植到其他例如Linux等平臺上,盡可能向Java的“一次編寫、到處可運(yùn)行”的理想境界靠攏。 五、源碼 /*所附的ZIP文件報(bào)含示例的全部工程文件,還有編譯后的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紀(jì)錄,可以幫助用戶理解系統(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 /實(shí)現(xiàn)線程控制多線程接口 /將啟動一組線程來監(jiān)聽多個(gè)服務(wù)請求 public static boolean STOP = false; /由系統(tǒng)來控制的內(nèi)部變量,決定著服務(wù)進(jìn)程(線程)的啟動、暫停等 public static boolean PAUSE = false; public int ListenThreadCount=0; /本服務(wù)支持的當(dāng)前線程數(shù)量 int maxSocket=10; /最大支持的同時(shí)連結(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+; /當(dāng)前線程的數(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 .*; /*實(shí)現(xiàn)每一個(gè)客戶連接到此NT服務(wù)時(shí)的服務(wù)器端的線程單元邏輯*/ public class EchoThread implements Runnable /實(shí)現(xiàn)線程接口 Sock

溫馨提示

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

評論

0/150

提交評論