1

クライアントサーバーベースのアプリケーションに通信プロトコルを実装したくなかったため、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、

マーカス

4

2 に答える 2

5

hosts fileフォームのエントリを含むマシンの にエントリを追加する必要があります

machinename    privateip

例えば

virtualmachine    192.168.1.16

localhostこれにより、RMI がホスト名を「call me back」アドレスとして送信するのを防ぐことができます。

このアプローチをテストするには、変更の前後に次のコードを実行します。

System.out.println(java.net.InetAddress.getLocalHost());

変更前はローカル アドレスを出力し、変更後は非ローカル アドレスを出力する必要があります。

于 2009-07-23T09:20:13.310 に答える
-2

サーバーごとに異なるバージョンのJDKを使用すると、この問題が発生する可能性があります。

java -versionコマンドを使用して、同じバージョンのjreを使用していることを確認します。

于 2009-07-22T19:25:25.723 に答える