2011-12-22 2 views
1

これはRMIに関連する質問です。私は4つの.classファイルを持っています。それは実装、クラスserver、クラスclientです。CMDで起動していないクラスの内容がどのように出力されるのですか

のrmiregistryを起動した後、私は似ているサーバを起動します。私は、関数を呼び出すリモートオブジェクトの参照を使用して

import java.rmi.Naming; 
import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.io.IOException; 


public class Client { 
    public static void main(String args[]) { 
     try { 
      to_Server_Intf s_Intf = (to_Server_Intf)Naming.lookup("rmi://127.0.0.1/Server"); 
      do { 
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
      String message_to_send = null; 
      System.out.println("===Enter your message==="); 
      message_to_send = br.readLine(); 
      // sending a message to the server 
      String reply = s_Intf.send(message_to_send); 
      System.out.println(reply); 
      }while(true); 
     }catch(Exception exc) { 
      System.out.println(exc); 
     } 
    } 
} 

import java.rmi.Naming; 


public class Server { 
    public static void main(String args[]) { 
     try { 
      to_Server_Impl toServer = new to_Server_Impl(); 
      Naming.rebind("Server", toServer); 
     } catch(Exception exc) { 
      System.out.println(exc); 
     } 
    } 
} 

そしてiはコードでクライアントを起動そのクラスのsendは、そのコードは次のようになります。

import java.rmi.*; 
import java.rmi.server.*; 
import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.io.IOException; 

public class to_Server_Impl extends UnicastRemoteObject implements to_Server_Intf{ 
    public to_Server_Impl() throws Exception{ } 

@Override 
public String send(String str){ // this function receives the message from the Client. 
    // this method indirectly replies,by calling reply and then returning the replies string 
    String receivedString = str;   
    System.out.println(receivedString); 
    System.out.println(); 
    String reply = reply(); 

    return reply; 
} 

@Override 
public String reply() { // this function replies the Client 
    String replyString = null; 
     try { 
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
      replyString = br.readLine(); 
     }catch(Exception exc) { 
      System.out.println(exc); 
     } 
    return replyString; 
} 
} 

上記のクラスのメソッドを上記クラスのprintのステートメントで呼び出すと、メッセージは "server"ウィンドウに表示されます。そんなことがあるものか ?

クライアントウィンドウ:(クライアントがメッセージを送信している)

enter image description here

サーバーウィンドウ:(メッセージは、サーバ・ウィンドウに印刷されます(コールがクラスto_Server_Implの機能に向けました)。どうやって?)

enter image description here

答えて

2

私はあなたの質問を理解していません。 sendメソッド(サーバー上にあります。つまり、サーバー上のクライアントからリモートで呼び出されます)では、受信したメッセージを印刷しています。したがって、サーバーコンソールに表示されます。

編集は:基本的にこれはRMIがどのように働くかある:

サーバーアプリケーションが呼び出される利用可能な方法とのインタフェースを公開しています。あなたの場合、これはto_Server_Intfです。サーバはまた、インタフェースの実装を有しており、to_Server_Implである。サーバーは、リモートオブジェクトをNaming.bind(またはNaming.rebind)でレジストリにパブリッシュします。

クライアントは、サーバー上のインターフェイスについてのみ認識しますが、実装については認識しません。彼らはレジストリを検索し、リモートオブジェクトをNaming.lookupという名前で見つけることができます。これで、クライアントはリモートオブジェクトインスタンスを持ち、メソッドを呼び出すことができます。このオブジェクト(クライアントコードのs_intf)は、実際にはサーバー上に存在するインターフェイス実装のローカルプロキシです。クライアントがこのプロキシ上のメソッドを呼び出すと、その呼び出しは実際にサーバー上のオブジェクトに送信されます。そのため、サーバーコンソールに文字列が表示されます。

クライアントがローカルスタブ上のメソッドを呼び出すときに実際に何が起こるかは、パラメータがあればそれがシリアル化され、TCPソケットメッセージ(または基礎となる実装が何であれ)が作成され、着信要求をリスンしています。サーバー側では、メッセージが受信され、パラメーターがデシリアライズされ、正しいメソッドがメッセージから識別され、呼び出されます。メソッドが戻ると、結果がシリアル化され、TCPメッセージが作成され、クライアントに返されます。

+0

私はクラス 'to_Server_Impl'のsendメソッドを呼び出しました。それは 'Server'コンソールにどのように現れますか? –

+0

to_Server_Implは、リモートオブジェクトのインタフェースの実装です。クライアントでは、Naming.lookupを使用してリモートオブジェクトを検索してからメソッドを呼び出します。このメソッドは実際にto_Server_Implによってサーバー上で実行されます。そのため、メッセージはサーバーに出力されます。 – Tudor

+0

RMIの仕組みについての説明が必要ですか? – Tudor

0

リモートオブジェクトです。サーバー上で実行されます。サーバー上に出力を印刷します。これがRMI の意味です。出力をクライアントに出力した場合、リモートオブジェクトではなくローカルオブジェクトでなければなりません。

関連する問題