RMI:RMI服务器同时只能使用一个网络接口吗



我有rmi服务器,我的计算机上有几个网络适配器。

为了不获得java.rmi.ConnectException: Connection refused to host: 127.0.1.1;,我需要在rmi服务器上设置java.rmi.server.hostname属性(请参阅https://stackoverflow.com/a/15696021/5057736)

这是否意味着在JVM的一个实例中,rmi服务器同时只能使用一个网络接口而不需要任何操作系统设置?

设置java.rmi.server.hostname只会影响写入存根的内容。它对听力没有影响。RMI总是在0.0.0.0侦听,除非您使用不侦听的RMIServerSocketFactory

阅读后https://community.oracle.com/blogs/emcmanus/2006/12/22/multihomed-computers-and-rmi这个https://community.oracle.com/thread/1178328?start=0我做了以下解决方案-在所有应用程序中,导出我们放在一个地方的RMIRemoteObjects。该解决方案允许RMI在JVM的一个实例中同时使用不同的网络接口。为每个套接字地址(网络接口+端口)创建RmiRemoteManager。在导出之前,我们需要定义java.rmi.server.hostname。此解决方案有效。请记住,这是RMI限制的变通方法。

class ClientSocketFactory implements RMIClientSocketFactory,Serializable{
    private InetAddress address;
    public ClientSocketFactory(InetAddress address)
    {
        this.address = address;
    }
    @Override
    public Socket createSocket(String host, int port) throws IOException {
        Socket socket =new Socket(address, port);
        return socket;
    }
    @Override
    public boolean equals(Object that)
    {
        return that != null && this.getClass() == that.getClass();
    }
}
class ServerSocketFactory implements RMIServerSocketFactory{
    private InetAddress address;
    public ServerSocketFactory(InetAddress address)
    {
        this.address = address;
    }
    @Override
    public ServerSocket createServerSocket(int port) throws IOException{  
        return new ServerSocket(port, 0, address);
    }
    @Override
    public boolean equals(Object that)
    {
        return that != null && this.getClass() == that.getClass();
    }
}
public class RmiRemoteManager {
    private Registry registry;
    private InetSocketAddress socketAddress;
    private ServerSocketFactory serverSocketFactory;
    private ClientSocketFactory clientSocketFactory;
    public RmiRemoteManager(InetSocketAddress socketAddress) {
        try {
            this.socketAddress = socketAddress;
            serverSocketFactory=new ServerSocketFactory(InetAddress.getByName(socketAddress.getHostName()));
            clientSocketFactory=new ClientSocketFactory(InetAddress.getByName(socketAddress.getHostName()));
            //the registry is exported via createRegistry.
            registry = LocateRegistry.createRegistry(this.socketAddress.getPort(),clientSocketFactory,serverSocketFactory);
        } catch (UnknownHostException ex) {
            Logger.getLogger(RmiRemoteManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (RemoteException ex) {
            Logger.getLogger(RmiRemoteManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    private synchronized static Remote export(Remote remoteObject,InetSocketAddress sa,ClientSocketFactory csf,ServerSocketFactory ssf){
        try {
            System.setProperty("java.rmi.server.hostname",sa.getHostName());
            return UnicastRemoteObject.exportObject(remoteObject,sa.getPort(),csf,ssf);
        } catch (RemoteException ex) {
            Logger.getLogger(RmiRemoteManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
    public void export(Remote remoteObject,String url){
        try {
            Remote stub=export(remoteObject,socketAddress,clientSocketFactory,serverSocketFactory);
            remoteObjects.add(remoteObject);
            if (url!=null){
                urlsByRemoteObjects.put(remoteObject, url);
                registry.rebind(url, stub);
            }
        } catch (RemoteException ex) {
            Logger.getLogger(RmiRemoteManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

最新更新