codefans

          導(dǎo)航

          <2012年6月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          統(tǒng)計(jì)

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          程序設(shè)計(jì)鏈接

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          Linux平臺(tái)下利用JNI+雙向RMI實(shí)現(xiàn)遠(yuǎn)程推送

          一、 前言 
          作為一種優(yōu)秀的編程語(yǔ)言,Java在許多方面具有突出的優(yōu)越性。其中,RMI技術(shù)充分展現(xiàn)了Java卓越的分布式計(jì)算能力,而JNI技術(shù)則體現(xiàn)了Java結(jié)合異種編程語(yǔ)言的強(qiáng)大能力。人們常說(shuō),RMI是“從Java到Java”,這種說(shuō)法忽視了這樣一個(gè)事實(shí):Java可利用JNI技術(shù)很容易地與原有系統(tǒng)連接。JNI+RMI的技術(shù)解決方案極大地延伸了Java的分布式功能。 
          本文的寫作是基于這樣一種實(shí)際需要:在實(shí)際運(yùn)行環(huán)境當(dāng)中,我們需要將一臺(tái)Linux網(wǎng)絡(luò)工作站產(chǎn)生的信息實(shí)時(shí)動(dòng)態(tài)的顯示在遠(yuǎn)程監(jiān)控者的機(jī)器上,以便他及時(shí)對(duì)該Linux工作站上發(fā)生的情況進(jìn)行處理。比如, Linux工作站上運(yùn)行著網(wǎng)絡(luò)入侵檢測(cè)系統(tǒng),檢測(cè)到的入侵信息必須實(shí)時(shí)地提供給遠(yuǎn)程監(jiān)控者,以便及時(shí)作出響應(yīng);再比如, Linux工作站上運(yùn)行著網(wǎng)絡(luò)管理系統(tǒng),產(chǎn)生的有關(guān)網(wǎng)絡(luò)流量和網(wǎng)絡(luò)性能的數(shù)據(jù)也必須及時(shí)提供給網(wǎng)絡(luò)管理人員。 
          而Linux平臺(tái)下的軟件,大多數(shù)是用C語(yǔ)言編寫的,這是一筆難以舍棄的財(cái)富。而且C語(yǔ)言與底層系統(tǒng)的緊密結(jié)合以及C的運(yùn)行速度,是Java所不具備。這就為JNI+RMI技術(shù)提供了廣闊的舞臺(tái)。 

          二、 JNI技術(shù) 
          Java以其跨平臺(tái)的特性得到廣泛應(yīng)用,其代碼可以一次編譯多處執(zhí)行。但正是這種特性 給它帶來(lái)了一定的局限性,一些與平臺(tái)相關(guān)的功能就不能很好地支持。幸運(yùn)的是Java提供了JNI技術(shù)——完備的C語(yǔ)言接口,讓我們可以利用C語(yǔ)言的強(qiáng)大功能來(lái)彌補(bǔ)Java的不足。很容易發(fā)現(xiàn)JNI在Java和本地應(yīng)用程序之間起著膠水的作用。圖1將描述JNI是如何將應(yīng)用程序的C語(yǔ)言部分和Java部分連接在一起的。圖1來(lái)源于Sun公司的Java指南。 

          三、 RMI技術(shù) 
          1、 運(yùn)行原理 
          RMI 應(yīng)用程序通常包括兩個(gè)獨(dú)立的程序:服務(wù)器程序和客戶機(jī)程序。典型的服務(wù)器應(yīng)用程序?qū)?chuàng)建多個(gè)遠(yuǎn)程對(duì)象,使這些遠(yuǎn)程對(duì)象能夠被引用,然后等待客戶機(jī)調(diào)用那些遠(yuǎn)程對(duì)象上的方法。而典型的客戶機(jī)程序則從服務(wù)器中得到一個(gè)或多個(gè)遠(yuǎn)程對(duì)象的引用,然后調(diào)用遠(yuǎn)程對(duì)象的方法。RMI 為服務(wù)器和客戶機(jī)進(jìn)行通訊和信息傳遞提供了一種機(jī)制。這樣的應(yīng)用程序有時(shí)被稱為分布式對(duì)象應(yīng)用程序。分布式對(duì)象應(yīng)用程序需要:(1)定位遠(yuǎn)程對(duì)象。它既可用 RMI 的簡(jiǎn)單命名工具 rmiregistry 來(lái)注冊(cè)它的遠(yuǎn)程對(duì)象,也可將遠(yuǎn)程對(duì)象引用作為常規(guī)操作的一部分來(lái)進(jìn)行傳遞和返回。(2)與遠(yuǎn)程對(duì)象通訊。遠(yuǎn)程對(duì)象間通訊的細(xì)節(jié)由 RMI 處理,對(duì)于程序員來(lái)說(shuō),遠(yuǎn)程通訊看起來(lái)就象標(biāo)準(zhǔn)的 Java 方法調(diào)用。(3)給作為參數(shù)或返回值傳遞的對(duì)象加載類字節(jié)碼。因?yàn)?RMI 允許調(diào)用程序?qū)⒓?Java 對(duì)象傳給遠(yuǎn)程對(duì)象,所以 RMI 將提供必要的機(jī)制,既可以加載對(duì)象的代碼又可以傳輸對(duì)象的數(shù)據(jù)。服務(wù)器調(diào)用注冊(cè)服務(wù)程序以使名字與遠(yuǎn)程對(duì)象相關(guān)聯(lián)。客戶機(jī)在服務(wù)器注冊(cè)服務(wù)程序中用遠(yuǎn)程對(duì)象的名字查找該遠(yuǎn)程對(duì)象,然后調(diào)用它的方法。RMI 能用 Java系統(tǒng)支持的任何 URL 協(xié)議(例如 HTTP、FTP、file 等)加載類字節(jié)碼。 
          下圖描繪了一個(gè)RMI分布式應(yīng)用程序 ,它通過(guò)registry得到一個(gè)遠(yuǎn)程對(duì)象的引用。服務(wù)器調(diào)用registry將遠(yuǎn)程對(duì)象連接(或者綁定)到一個(gè)名字上。客戶端在服務(wù)器的 registry上根據(jù)那個(gè)名字查找遠(yuǎn)程對(duì)象,并且調(diào)用名字上的一個(gè)方法。圖2同時(shí)顯示出每當(dāng)需要時(shí),RMI系統(tǒng)使用一個(gè)Web服務(wù)器來(lái)裝載類字節(jié)碼,從服務(wù)器到客戶端并且從顧客到服務(wù)器。圖2來(lái)源于Sun公司的Java指南。 

          2、 雙向RMI技術(shù) 
          前面講到通常情況下在RMI應(yīng)用程序中,是服務(wù)器程序提供遠(yuǎn)程方法給客戶機(jī)程序調(diào)用。但是某種情況下,RMI應(yīng)用程序同時(shí)也需要客戶機(jī)程序提供遠(yuǎn)程方法給服務(wù)器程序調(diào)用。也就是說(shuō),某種情況下,RMI應(yīng)用程序的兩個(gè)部分同時(shí)具有服務(wù)器和客戶機(jī)的功能。 
          比如,你的遠(yuǎn)程客戶希望可以通過(guò)瀏覽器實(shí)時(shí)查看Linux平臺(tái)下程序運(yùn)行的產(chǎn)生的信息。那么從技術(shù)上說(shuō):遠(yuǎn)程客戶機(jī)器上運(yùn)行的Applet程序是RMI服務(wù)器程序,而Linux平臺(tái)下程序是RMI客戶機(jī)程序。Linux平臺(tái)下程序通過(guò)RMI調(diào)用Applet程序的相關(guān)方法,將信息實(shí)時(shí)推送到遠(yuǎn)程客戶機(jī)器。這是一個(gè)非常典型的RMI應(yīng)用。 
          但是這里出現(xiàn)了一個(gè)問(wèn)題:遠(yuǎn)程客戶機(jī)器的IP地址沒(méi)有辦法確定,遠(yuǎn)程客戶應(yīng)該可以從任何連接到Internet的機(jī)器上訪問(wèn)到這些信息。如果不知道IP地址,Linux平臺(tái)下程序不可能通過(guò)URL訪問(wèn)遠(yuǎn)程Applet程序中的RMI方法。 
          因此這里必須使用雙向RMI技術(shù)。首先由遠(yuǎn)程Applet程序通過(guò)URL調(diào)用Linux平臺(tái)下程序的RMI方法,建立起RMI連接。然后,再由Linux平臺(tái)下程序調(diào)用遠(yuǎn)程Applet程序中RMI來(lái)推送信息。 

          四、 程序?qū)嵗?nbsp;
          關(guān)于Linux平臺(tái)下C程序的輸出,可以是網(wǎng)絡(luò)入侵檢測(cè)系統(tǒng),網(wǎng)絡(luò)管理系統(tǒng),或者其他系統(tǒng)。這里為了簡(jiǎn)化程序,用一個(gè)簡(jiǎn)單的C程序代替。該程序?qū)⒛阍贚inux平臺(tái)下輸入的字符串,回顯到遠(yuǎn)端客戶瀏覽器上。 
          1、 編寫Java文件CreatMessage.java 
          里面包含一些native的函數(shù),這些函數(shù)就是將在C中要實(shí)現(xiàn)的。另外程序?qū)⒙暶饕粋€(gè)調(diào)用RMI方法的Java私有方法,該方法將在C程序中被調(diào)用。源程序如下: 
          class CreatMessage{ 
          MessageServerImpl ms; 
          //聲明一個(gè)本地方法接口函數(shù) 
          public native void creatmsa(); 
          //聲明一個(gè)Java方法,該方法將在C程序中被調(diào)用 
          private void pushMessage(String message){ 
          //新建一個(gè)RMI遠(yuǎn)程對(duì)象,并對(duì)其賦值 
          Message msa = new Message(); 
          msa.MessageString = message; 
          // notifyEvent方法將調(diào)用RMI方法notifiedEvent(Message msa) 
          try{ 
          ms.notifyEvent(msa); 
          } catch(Exception e){ 
          System.out.println("notifyEvent Exception:"+e.getMessage()); 
          }//catch end 

          //構(gòu)造函數(shù)負(fù)責(zé)傳遞MessageServerImpl對(duì)象的實(shí)例 
          public CreatMessage(MessageServerImpl msserver){ 
          ms = msserver; 



          2、 編譯CreatMessage.java文件,生成C語(yǔ)言頭文件CreatMessage.h 
          用Javac CreatMessage.java命令編譯Java源文件,生成CreatMessage.class,再用Javah CreatMessage命令生成C語(yǔ)言頭文件CreatMessage.h 
          /* DO NOT EDIT THIS FILE - it is machine generated */ 
          #include <jni.h> 
          /* Header for class CreatMessage */ 
          #ifndef _Included_CreatMessage 
          #define _Included_CreatMessage 
          #ifdef __cplusplus 
          extern "C" { 
          #endif 
          /* 
          * Class: CreatMessage 
          * Method: creatmsa 
          * Signature: ()V 
          */ 
          JNIEXPORT void JNICALL Java_CreatMessage_creatmsa 
          (JNIEnv *, jobject); 
          #ifdef __cplusplus 

          #endif 
          #endif 
          這是由javah命令生成的文件,不需要也不允許進(jìn)行任何修改。我們注意到這里有一段程序 “JNIEXPORT void JNICALL Java_CreatMessage_creatmsa (JNIEnv *, jobject);”。Java_CreatMessage_creatmsa 提供了CreatMessage.class中本地方法的具體實(shí)現(xiàn),當(dāng)你編寫本地方法的實(shí)現(xiàn)程序時(shí),你將使用相同的方法簽名。如果CreatMessage.class含有其他的本地方法,這些方法的簽名同樣會(huì)在頭文件中出現(xiàn)。 

          3、 編寫creatmsa.c,實(shí)現(xiàn)本地方法 
          首先我們將如何得到Java方法的簽名呢?有兩種方法,一種是依據(jù)生成規(guī)則手工推算,另外Java 類文件反匯編程序工具javap ,可以幫助你消除手工推算方法簽名時(shí)發(fā)生的錯(cuò)誤。你能使用javap工具為指定的類打印出成員變量和方法簽名:javap -s -p CreatMessage。 
          要在C程序中調(diào)用Java方法,需要完成下面三個(gè)步驟: 
          (1) 在C程序中調(diào)用JNI方法GetObjectClass,它將返回該Java對(duì)象的Java類對(duì)象。 
          (2) 接著調(diào)用JNI方法GetMethodID,它將在一個(gè)給定的類文件中查找Java方法。該查找是基于方法名字以及方法簽名。如果該方法不存在,GetMethodID將返回0。程序?qū)⒘⒓捶祷兀伋鯪oSuchMethodError。 
          (3) 將調(diào)用JNI方法CallVoidMethod。該方法將激活一個(gè)返回值為void的實(shí)例方法。你必須將object, method ID以及該方法的參數(shù)傳遞給CallVoidMethod。 

          creatmsa.c源程序如下: 
          #include <stdio.h> 
          #include <jni.h> 
          #include "CreatMessage.h" 
          static jclass cls ; 
          static jmethodID mid ; 
          JNIEXPORT void JNICALL Java_CreatMessage_creatmsa(JNIEnv *env, jobject obj) 

          char buff[128]; 
          jstring message; 
          //將用戶輸入字符串,賦值給buff 
          scanf("%s", buff); 
          //將buff的值轉(zhuǎn)換成UTF格式,并賦給message 
          message = (*env)->NewStringUTF(env,buff); 
          cls = (*env)->GetObjectClass(env, obj); 
          mid = (*env)->GetMethodID(env, cls, "pushMessage", "(Ljava/lang/String;)V"); 
          if (mid == 0){ 
          printf("GetMethodID error"); 
          return; 

          (*env)->CallVoidMethod(env, obj, mid, message); 


          4、 編譯creatmsa.c,生成libcreatmsa.so 
          在Linux平臺(tái)下編譯creatmsa.c,要格外注意路徑問(wèn)題。最經(jīng)常出現(xiàn)的錯(cuò)誤就是因?yàn)槁窂皆O(shè)置不對(duì),而引起的無(wú)法找到編譯所需要的文件。本文中使用jdk1.3.1的目錄為/url/local/j2sdk1.3.1,所有例子程序都存放在/rmitest目錄下。因此本文路徑設(shè)置為: 
          classpath = /rmitest: 
          /url/local/j2sdk1.3.1/include: 
          /url/local/j2sdk1.3.1/jre/lib/i386 
          export classpath 
          LD_LIBRARY_PATH = /rmitest: 
          /url/local/j2sdk1.3.1/jre/lib/i386: 
          /url/local/j2sdk1.3.1/jre/lib/i386/native_threads: 
          /url/local/j2sdk1.3.1/jre/lib/i386/classic: 
          $LD_LIBRARY_PATH 
          export LD_LIBRARY_PATH 
          設(shè)置完路徑以后,就可以開(kāi)始編譯程序了,使用命令: 
          gcc -I//url/local/j2sdk1.3.1/include 
          -I//url/local/j2sdk1.3.1/include/linux 
          -shared 
          creatmsa.c -o libcreatmsa.so 

          5、 Message.java 
          在RMI分布式應(yīng)用系統(tǒng)中,服務(wù)器與客戶機(jī)之間傳遞的Java對(duì)象必須是可序列化的對(duì)象。不可序列化的對(duì)象不能在對(duì)象流中進(jìn)行傳遞。因此,我們必須生成一個(gè)Java類以傳遞參數(shù)。這個(gè)類定義的很簡(jiǎn)單,在實(shí)際運(yùn)用中,可以根據(jù)需要增加內(nèi)容。 
          import java.io.Serializable; 
          import java.io.*; 
          public class Message implements Serializable 

          String MessageString; 


          6、 MessageServer.java 
          定義兩個(gè)RMI接口。它們將在MessageServerImpl.java程序中實(shí)現(xiàn)。 
          import java.rmi.Remote; 
          import java.rmi.RemoteException; 
          public interface MessageServer extends Remote { 
          void newClient(MessageClient mc) throws RemoteException; 
          void removeClient(MessageClient mc) throws RemoteException; 


          7、 MessageServerImpl.java 
          實(shí)現(xiàn)在MessageServer.java程序中定義的RMI接口。 
          import java.rmi.*; 
          import java.rmi.server.*; 
          import java.util.Vector; 
          public class MessageServerImpl extends UnicastRemoteObject implements MessageServer 

          Vector clients=new Vector(); 
          public MessageServerImpl() throws RemoteException { 
          super(); 

          public void newClient(MessageClient mc) throws RemoteException { 
          clients.addElement(mc); 

          public void removeClient(MessageClient mc) throws RemoteException { 
          clients.removeElement(mc); 

          public void notifyEvent(Message msa) throws RemoteException { 
          Vector tc=(Vector)clients.clone(); 
          for (int i=0;i<tc.size();i++){ 
          try { 
          ((MessageClient)(tc.elementAt(i))).notifiedEvent(msa); 
          } catch(Exception e){ 
          removeClient((MessageClient)(tc.elementAt(i))); 





          8、 MessageClient.java 
          定義兩個(gè)RMI接口。它們將在MessageClientImpl.java程序中實(shí)現(xiàn)。 
          import java.rmi.Remote; 
          import java.rmi.RemoteException; 
          public interface MessageClient extends Remote { 
          void notifiedEvent(Message msa) throws RemoteException; 


          9、 MessageClientImpl.java 
          實(shí)現(xiàn)在MessageClient.java程序中定義的RMI接口。 
          import java.rmi.*; 
          import java.rmi.server.*; 
          import javax.swing.*; 
          import java.awt.*; 
          public class MessageClientImpl extends UnicastRemoteObject implements MessageClient 

          JTextArea jt; 
          static String ipAddr="255.255.255.255"; 
          public void notifiedEvent(Message msa) throws RemoteException { 
          jt.insert(msa.MessageString+"\n",0); 

          public MessageClientImpl(JTextArea jtext) throws RemoteException { 
          super();//調(diào)用其父類的構(gòu)造函數(shù)UnicastRemoteObject 
          jt=jtext; 

          public void init() throws RemoteException{ 
          try { 
          String name = "http://"+ipAddr+":1099/MessageServer"; 
          MessageServer fs = (MessageServer)Naming.lookup(name); 
          fs.newClient(this); 
          } catch(Exception e){ 
          System.err.println("MessageClient exception: " + e.getMessage()); 


          public void setIPaddr(String str) 

          ipAddr = str; 



          10、 編譯生成Stub文件 
          利用命令rmic -v1.2 MessageClientImpl和命令rmic -v1.2 MessageServerImpl 
          分別生成MessageClientImpl_Stub.class文件和MessageServerImpl_Stub.class文件 

          11、 StartServer.java 
          編寫StartServer.java文件,初始化RMI運(yùn)行環(huán)境如啟動(dòng)rmigegistry,設(shè)置RMISecurityManager,綁定RMI對(duì)象等等。并加栽C程序生成的動(dòng)態(tài)連接庫(kù)文件libcreatmsa.so。 
          import java.rmi.*; 
          import java.rmi.RemoteException; 
          import java.rmi.RMISecurityManager; 
          import java.rmi.registry.LocateRegistry; 
          public class StartServer{ 
          static { 
          System.loadLibrary("creatmsa");/*actual name is "libcreatmsa.so"*/ 

          public static void main(String args[]) 

          if(System.getSecurityManager() == null) 
          System.setSecurityManager(new RMISecurityManager()); 
          try{ 
          LocateRegistry.createRegistry(1099); 
          //注冊(cè)IDS處理服務(wù)器 
          MessageServerImpl msObj = new MessageServerImpl(); 
          Naming.rebind("http://127.0.0.1:1099/MessageServer",msObj); 
          //啟動(dòng)c程序 
          CreatMessage cm = new CreatMessage(msObj); 
          cm.creatmsa(); 
          } catch (Exception e){ 
          System.out.println("registe error: " + e.getMessage()); 




          12、 MessageEcho.java 
          編寫遠(yuǎn)程客戶端的Applet程序,調(diào)用RMI方法,與服務(wù)器建立連接。并一個(gè)Panel上顯示Linux平臺(tái)下程序產(chǎn)生的數(shù)據(jù)。 
          import java.awt.*; 
          import java.applet.Applet; 
          import javax.swing.*; 
          import java.rmi.RMISecurityManager; 
          public class MessageEcho extends JApplet{ 
          Container contentPane = getContentPane(); 
          JPanel panel = new JPanel(new BorderLayout()); 
          JPanel alarmPanel;//顯示Linux平臺(tái)下程序產(chǎn)生的數(shù)據(jù)的模板 
          //顯示Linux平臺(tái)下程序產(chǎn)生的數(shù)據(jù)的區(qū)域 
          final JTextArea alarmList=new JTextArea(8,40); 
          //運(yùn)行Linux平臺(tái)下程序的機(jī)器的IP地址 
          String ipServer; 
          public void init() { 
          ipServer = getParameter("AppServer"); //此項(xiàng)在test.html中賦值 
          alarmPanel=new JPanel(); 
          alarmList.insert("\nSome message here"+"\n",0); 
          alarmPanel.setLayout(null); 
          alarmList.setLineWrap(true); 
          alarmList.setWrapStyleWord(true); 
          JScrollPane areaScrollPane = new JScrollPane(alarmList); 
          areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 
          areaScrollPane.setPreferredSize(new Dimension(200, 120)); 
          alarmPanel.add(areaScrollPane); 
          areaScrollPane.setBounds(0,40,200,120); 
          panel.add(alarmPanel,BorderLayout.CENTER); 
          contentPane.add(panel); 
          try{ 
          MessageClientImpl mci=new MessageClientImpl(alarmList); 
          mci.setIPaddr(ipServer); 
          mci.init(); 
          } catch (Exception e) { 
          System.err.println("alarmListener exception: " + e.getMessage()); 
          e.printStackTrace(); 




          13、 Test.html 
          在HTML文件中調(diào)用Applet的類文件。其中AppServer是Linux工作站的IP地址。 
          <HTML> 
          <BODY> 
          <COMMENT> 
          <EMBED width="750" height="400" 
          align="baseline" code="MessageEcho.class" codebase="." 
          AppServer="202.114.33.87" ><!--應(yīng)用服務(wù)器地址,即Linux工作站的IP地址--> 
          </EMBED> 
          </BODY> 
          </HTML> 

          14、 修改java.policy文件 
          為了允許客戶程序同RMI注冊(cè)程序和服務(wù)器對(duì)象連接,你需要提供一個(gè)策略文件(policy file)。策略文件是非常復(fù)雜的問(wèn)題。這里只提供一個(gè)修改的樣本,它賦予程序絕大多數(shù)的操作權(quán)限。這樣使你調(diào)試類似程序時(shí)候非常方便,但是也請(qǐng)注意這種做法給你的計(jì)算機(jī)帶來(lái)的潛在危險(xiǎn)。希望進(jìn)一步了解安全策略文件的讀者可以看看參考文獻(xiàn)8。 
          java.policy文件內(nèi)容如下: 
          grant { 
          permission java.security.AllPermission; 
          }; 
          因?yàn)楸疚闹惺褂玫氖请p向RMI,所以你必須同時(shí)修改兩臺(tái)機(jī)器的策略文件。在RedHat7.1中需要將java.policy文件拷貝到/url/local/j2sdk1.3.1/jre/lib/security目錄,在Windows2000中是c:\j2sdk1.3.1\jre\lib\security目錄。當(dāng)然你需要根據(jù)你機(jī)器上的java目錄做相應(yīng)調(diào)整。 

          五、 實(shí)現(xiàn)環(huán)境以及運(yùn)行步驟 
          一臺(tái)機(jī)器操作系統(tǒng)為RedHat7.1,文件有:MessageServer.class,MessageServerImpl.class,MessageServerImpl_Stub.class,Message.class,MessageClient.class,MessageClientImpl_Stub.class,libcreatmsa.so,所有文件均在同一目錄下面。 
          一臺(tái)機(jī)器操作系統(tǒng)為Windows2000,文件有:MessageClient.class,MessageClientImpl.class,MessageClientImpl_Stub.class,Message.class,MessageServer.class,MessageServerImpl_Stub.class,MessageEcho.class,test.html,所有文件均在同一目錄下面。 
          1、 首先修改兩臺(tái)機(jī)器上的java.policy文件; 
          2、 然后在RedHat7.1的機(jī)器上設(shè)置路徑,即運(yùn)行上文提到的相應(yīng)命令; 
          3、 然后在RedHat7.1的機(jī)器上運(yùn)行命令:java StartServer; 
          4、 然后在Windows2000的機(jī)器上運(yùn)行命令:appletviewer test.html; 
          5、 接著在RedHat7.1的機(jī)器上隨意輸入一字符傳后敲回車鍵,該字符串將回顯在Windows2000機(jī)器的Appletviewer窗口中

          posted on 2005-11-06 15:34 春雷的博客 閱讀(1730) 評(píng)論(1)  編輯  收藏

          評(píng)論

          # re: Linux平臺(tái)下利用JNI+雙向RMI實(shí)現(xiàn)遠(yuǎn)程推送[未登錄](méi) 2012-06-26 12:02

          他  回復(fù)  更多評(píng)論   


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 杭州市| 襄樊市| 兖州市| 南京市| 四会市| 涟源市| 保靖县| 武鸣县| 郸城县| 黑河市| 乐亭县| 白玉县| 兴安县| 井陉县| 田阳县| 土默特左旗| 曲沃县| 贵州省| 阳原县| 兴山县| 刚察县| 克山县| 岫岩| 西乌珠穆沁旗| 香港 | 资源县| 渝北区| 敦煌市| 家居| 探索| 藁城市| 阿瓦提县| 宝清县| 乌拉特中旗| 柳河县| 新绛县| 织金县| 无棣县| 肃南| 金堂县| 镇江市|