【问题标题】:RMI Server to Client call fails when Client machine has more than one IP Address当客户端机器具有多个 IP 地址时,RMI 服务器到客户端调用失败
【发布时间】:2012-04-27 16:51:22
【问题描述】:

首先,我很想为这个问题发布一些真实的代码,但我不能,因为它太多行了。也就是说,这是我的情况:

服务器端

我有一个 RMI 服务器,它等待客户端连接并“注册”自己,以便服务器可以对客户端进行函数调用。基本上,服务器有一个发布的函数,其工作方式类似于以下伪代码:

public class Server extends UnicastRemoteObject implements ServerInterface{
    public Server(){ /* Server publishes itself here */ }

    ...

    /** One of many methods visible to a remote Client */
    public void registerClient(Client c) throws RemoteException{
        //1. Make some remote calls on 'c' for book-keeping purposes
        //2. Store reference to c to make calls on it later
    }
}

客户端

在启动时,客户端调用Naming.lookup([url]) 以获取服务器的存根,我将调用serverRef,然后调用serverRef.registerClient(this)。问题发生在服务器的registerClient(Client c) 方法的第一行。

问题

当服务器在registerClient 方法内对Client 进行第一次远程方法调用时,会引发RemoteException。虽然客户端和服务器机器在同一个子网上,但客户端机器有一个辅助 IP 地址。所以 IP 看起来像这样:

服务器机器 IP:123.45.67.1
客户端计算机 IP:123.45.67.2192.168.67.2

在服务器第一次远程回调客户端期间抛出的 RemoteException 表明服务器正在尝试连接到客户端的 192.168.67.2 地址,这就是导致失败的原因。服务器应该尝试连接到 123.45.67.1 地址。我知道禁用属于第二个 IP 地址的网络接口可以解决问题,但这对我来说并不是一个真正的选择。

在打开与新客户端对象存根的连接时,有什么方法可以“告诉”服务器端 RMI 连接哪个 IP 地址?

【问题讨论】:

  • 如果您使用的是强托管模型操作系统,可以指定源 IP 地址。如果您使用的是弱托管模型操作系统(例如 Linux),操作系统会忽略您对源 IP 的提示并遵循其路由表。 (假设您可以通过这种方式让 RMI 使用 Socket)

标签: java rmi


【解决方案1】:

有几种可能的解决方案,包括

  • 编写自定义客户端套接字工厂

  • 在 java.rmi.server.hostname 属性中指定地址

    -Djava.rmi.server.hostname=ip_address

查看此链接:

这些链接也很有用:

【讨论】:

  • 感谢您的链接!我想我要编写一个自定义客户端套接字工厂 - 我会让你知道它是怎么回事。
  • 是的,成功了。我最终实现了自己的RMISocketFactory 并在套接字工厂的createSocket(String host, int port) 方法中使用了RemoteServer.getClientHost(),最终被我的registerClient(c) 方法调用。我只需将给定的主机名替换为调用getClientHost() 返回的主机名,它每次都能完美运行。谢谢!
  • 嗨,本,我也有同样的问题。能把上面说的代码公布一下吗?
猜你喜欢
  • 2010-12-31
  • 2016-10-15
  • 1970-01-01
  • 2018-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多