クライアントサーバーベースのアプリケーションに通信プロトコルを実装したくなかったため、2つのコンポーネント間の情報交換のためにRMIクライアントとRMIサーバーを両側に実装しました。
同じマシンで2つのコンポーネントを起動してアプリケーションを使用しようとすると、すべてが正常に機能しています。しかし、コンポーネントを2つの異なるコンピューター(ファイアウォールが無効になっているWindows 7RC環境内の仮想マシンとしてのKubuntu9.04とネイティブのUbuntu9.04環境)に分割すると、RMIクライアントは次のメソッドを実行できないようです。サーバー側で定義されます。(すべての関数呼び出しはRMI例外につながります。)
現在、両側のシステムプロパティ「java.rmi.server.hostname」を、データ交換に使用する必要のあるネットワークインターフェイスに設定し、rmiデーモン(?)rmidとの通信用のデフォルトポートを登録しました。
誰かが何がうまくいかないのか考えていますか?使用できるようにするには、「java.rmi.server.codebase」(http://java.sun.com/j2se/1.4.2/docs/guide/rmi/javarmiproperties.html)などの他のパラメータを設定する必要がありますか?アプリケーション内のRMI機能?
編集:さて、ここにあなたのためのいくつかの追加情報があります:
初期化フェーズで、クライアントはサーバーコンポーネントのRMIサーバーへの接続を確立しようとします。これは、次の2つの方法を使用して初期化されました。
private void initialize()
{
// set ip address of rmi server
System.setProperty("java.rmi.server.hostname", ipAddress);
// try to register rmi server
try
{
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
}
catch (Exception e)
{
// ignore
}
}
public void start()
{
System.out.print("starting master control RMI server ...");
try
{
Naming.rebind("MasterControl", this);
}
catch (Exception e)
{
System.out.println("error: could not initialize master control RMI server");
System.exit(1);
}
// set running flag
isRunning = true;
System.out.println(" done");
}
「ipAddress」は、サーバーコンポーネントのネットワークインターフェイスのIPアドレスです。
クライアントコンポーネントが接続を確立するために使用するメソッドは、次のようになります。
public void connect()
{
// build connection url
String url = "rmi://" + masterControlIpAddress + "/MasterControl";
System.out.println(url);
System.out.print("connecting to master control ...");
// try to connect to master control server
while (connection == null)
{
try
{
connection = (MasterControlInterface) Naming.lookup(url);
id = connection.register(localIpAddress);
}
catch (Exception e)
{
// ignore
}
if (connection == null)
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
System.out.println(" done");
}
ご覧のとおり、クライアントが関数を呼び出してサーバーに接続を登録します。
@Override
public int register(String ipAddress) throws RemoteException
{
// add connection to registrationHandler
masterControl.registrationHandler.addConnection(ipAddress);
// log
int connectionCount = masterControl.registrationHandler.getConnectionCount();
System.out.println("slave control (" + ipAddress + ") instance has been registered at the master control server under the following id: " + connectionCount);
return connectionCount;
}
実際のネットワーク接続を使用してプログラムを実行すると、「スレーブ制御...」というテキストがサーバー側に表示されません。したがって、関数が実際にクライアントコンポーネントによって呼び出されているかどうかはわかりません。
クライアントコンポーネントが初期化された後、サーバーへのRMI接続を使用して次のメソッドを呼び出すことにより、サーバーコンポーネントに通知しようとします。
public void sendInitializationDone()
{
try
{
connection.initializationDone();
}
catch (RemoteException e)
{
System.out.println("error: could not send 'initializationDone' message to master control");
System.out.println(e);
System.exit(1);
}
}
サーバー側でフラグを設定します。
エラーは、クライアント側のこの関数内で発生します。
java.rmi.ConnectException:ホスト127.0.1.1への接続が拒否されました。ネストされた例外は次のとおりです。java.net.ConnectException:接続が拒否されました。
ホストがここにいる理由がわかりません127.0.1.1..。
@nos
もちろん、Windowsファイアウォールとカスペルスキーインターネットセキュリティの保護メカニズムを無効にしました。Kubuntuにファイアウォールが実行されているとは思いません。generellでは、プログラムを他のマシンにコピーするためにすでにscpを使用しているため、接続を確立することができます。
Edit2:
うーん、マシンを参照する/ etc / hostsのエントリをマシンのIPアドレスに設定した後、それは機能しているように見えますが、なぜそれが機能するのか本当に理解していません...
BR、
マーカス