我如何配置RMI环境,以便我能够在“真实”环境中使用它。网络? [英] How do I have to configure a RMI environment so that I'm able to use it in a "real" network?

查看:97
本文介绍了我如何配置RMI环境,以便我能够在“真实”环境中使用它。网络?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因为我不想为基于客户端服务器的应用程序实现通信协议,所以我在两端都实现了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功能吗? / p>

编辑:好的,这里有一些额外的信息:



在初始化阶段,我的客户端尝试建立与服务器组件的RMI服务器的连接,使用以下两种方法初始化:

  private void initialize()
{
//设置rmi服务器的IP地址
System.setProperty(java.rmi.server.hostname,ipAddress);

//尝试注册rmi服务器
尝试
{
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
}
catch(例外e)
{
//忽略
}
}

public void start()
{
System.out.print(启动主控制RMI服务器...);

尝试
{
Naming.rebind(MasterControl,这个);
}
catch(例外e)
{
System.out.println(错误:无法初始化主控制RMI服务器);
System.exit(1);
}

//设置运行标志
isRunning = true;

System.out.println(完成);
}

ipAddress在这里是服务器组件的网络接口的IP地址。



客户端组件用于建立连接的方法如下所示:

  public void connect()
{
//构建连接url
字符串url =rmi://+ masterControlIpAddress +/ MasterControl;

System.out.println(url);

System.out.print(连接到主控制器......);

//尝试连接到主控制服务器
而(连接== null)
{
尝试
{
connection =( MasterControlInterface)Naming.lookup(url);
id = connection.register(localIpAddress);
}
catch(例外e)
{
//忽略
}

if(connection == null)
{
try
{
Thread.sleep(100);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}

System.out.println(完成);
}

正如您所见,我的客户端调用一个函数来在服务器上注册连接:

  @Override 
public int register(String ipAddress)throws RemoteException
{
/ /添加与registrationHandler的连接
masterControl.registrationHandler.addConnection(ipAddress);

// log
int connectionCount = masterControl.registrationHandler.getConnectionCount();
System.out.println(slave control(+ ipAddress +)实例已在主控制服务器上注册以下id:+ connectionCount);

return connectionCount;
}

如果我使用真实的网络连接运行我的程序,文本奴隶控制...未显示在服务器端。因此,我不确定该函数是否真的由客户端组件调用。



客户端组件初始化后,它会尝试通过调用以下方法通知服务器组件使用它与服务器的RMI连接的方法:

  public void sendInitializationDone()
{
try
{
connection.initializationDone();
}
catch(RemoteException e)
{
System.out.println(错误:无法向主控制器发送'initializationDone'消息);
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:



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



BR,



Markus

解决方案

您需要在包含表格条目的机器的 hosts文件中添加一个条目

  machinename privateip 

例如

  virtualmachine 192.168.1.16 

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



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

  System.out.println(java.net.InetAddress.getL ocalHost()); 

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


Because I didn't want to implement a communication protocol for my client-server based application, I implemented a RMI client and a RMI server on both sides for the information exchange between the two components.

If I try to use my application by starting the two components on the same machine, everything is working fine. But if I split the components to two different computers (Kubuntu 9.04 within as a virtual machine within an Windows 7 RC environment with disabled firewall and a native Ubuntu 9.04 environment), it seems like the RMI client is not able to execute the methods which are defined on the server side. (Every functions call leads to a RMI exception.)

Currently I only set the system property "java.rmi.server.hostname" on both sides to the network interface which should be used for the data exchange and registered the default port for the communication with rmi daemon (?) rmid.

Does somebody has an idea what might be going wrong? Do I have to set some other parameters like "java.rmi.server.codebase" (http://java.sun.com/j2se/1.4.2/docs/guide/rmi/javarmiproperties.html) to be able to use the RMI functionality within my application?

Edit: Okay, here is some additional information for you:

In the initialization phase my client tries to establish a connection to the RMI server of server component, which was initialized using the following two methods:

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" is here the ip address of the network interface of the server component.

The method which is used by the client component to establish the connection looks like this:

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

As you can see my client calls a function to register the connection at the server:

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

If I run my program using a real network connection, the text "slave control ..." is not displayed on the server side. Therefore I'm not sure, if the function is really called by the client component.

After the client component is intialized it tries to notify the server component by calling the following method using it's RMI connection to the server:

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

to set a flag on the server side.

The error occures inside this function on the client side:

java.rmi.ConnectException: Connection refused to host 127.0.1.1; nested exception is: java.net.ConnectException: Connection refused.

I have no idea why the host is here 127.0.1.1 ...

@nos

Of course, I disabled the windows firewall and the protection mechanismn of Kaspersky Internet Security. I don't think that there is a running firewall in my Kubuntu. In generell it is possible to establish a connection, because I already used scp to copy my program to the other machine.

Edit2:

Mhhh, after setting the entry in /etc/hosts which refers to the machine to the ip address of the machine it seems to work, but don't really understand why it does ...

BR,

Markus

解决方案

You need to add an entry to the hosts file of the machines containing an entry of the form

machinename    privateip

e.g.

virtualmachine    192.168.1.16

This will prevent RMI from sending the localhost host name as a 'call me back' address.

To test this approach, run the following code before and after performing the change.

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

It should output a local address before the changes and a non-local address after the changes.

这篇关于我如何配置RMI环境,以便我能够在“真实”环境中使用它。网络?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆