当前位置:  开发笔记 > 编程语言 > 正文

如何配置RMI环境以便我能够在"真实"网络中使用它?

如何解决《如何配置RMI环境以便我能够在"真实"网络中使用它?》经验,为你挑选了1个好方法。

因为我不想为基于客户端服务器的应用程序实现通信协议,所以我在两端都实现了RMI客户端和RMI服务器,以便在两个组件之间进行信息交换.

如果我尝试通过在同一台机器上启动两个组件来使用我的应用程序,一切正常.但是,如果我将组件拆分为两台不同的计算机(Kubuntu 9.04作为具有禁用防火墙和本机Ubuntu 9.04环境的Windows 7 RC环境中的虚拟机),似乎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服务器的连接,该服务器组件使用以下两种方法进行初始化:

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;
}

如果我使用真实网络连接运行我的程序,则服务器端不会显示文本"slave control ...".因此,我不确定,该函数是否真的由客户端组件调用.

在客户端组件初始化之后,它尝试通过使用它与服务器的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

当然,我禁用了Kaspersky Internet Security的Windows防火墙和保护机制.我认为我的Kubuntu中没有运行防火墙.在generell中,可以建立连接,因为我已经使用scp将我的程序复制到另一台机器.

EDIT2:

嗯,在/ etc/hosts中设置条目后,将机器引用到机器的ip地址似乎可以工作,但是不明白它为什么会这样做......

BR,

马库斯



1> Robert Munte..:

您需要hosts file在包含表单条目的计算机中添加一个条目

machinename    privateip

例如

virtualmachine    192.168.1.16

这将阻止RMI将localhost主机名称作为"回拨"地址发送.

要测试此方法,请在执行更改之前和之后运行以下代码.

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

它应该在更改之前输出本地地址,在更改之后输出非本地地址.

推荐阅读
Chloemw
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有