Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否有一种方法可以确定远程RMI服务器计算机是否是多主机的,即使其某些IP地址不可见?_Java_Sockets_Rmi - Fatal编程技术网

Java 是否有一种方法可以确定远程RMI服务器计算机是否是多主机的,即使其某些IP地址不可见?

Java 是否有一种方法可以确定远程RMI服务器计算机是否是多主机的,即使其某些IP地址不可见?,java,sockets,rmi,Java,Sockets,Rmi,我在让RMI服务器在多主机机器上正常工作时遇到了一些障碍。我已经编写了一个定制的RMISocketFactory,并尝试用几种不同的方法实现客户端createSocket(字符串主机,int端口)方法。一种方法仅在RMI服务器计算机是多主机时有效,另一种方法仅在RMI服务器计算机不是多主机时有效。以下是我在客户端RMISocketFactory实现中的createSocket方法版本的代码: 仅当RMI服务器不是多宿主服务器时才起作用: @Override public Socket creat

我在让RMI服务器在多主机机器上正常工作时遇到了一些障碍。我已经编写了一个定制的
RMISocketFactory
,并尝试用几种不同的方法实现客户端
createSocket(字符串主机,int端口)
方法。一种方法仅在RMI服务器计算机是多主机时有效,另一种方法仅在RMI服务器计算机不是多主机时有效。以下是我在客户端
RMISocketFactory
实现中的
createSocket
方法版本的代码:

仅当RMI服务器不是多宿主服务器时才起作用:

@Override
public Socket createSocket(String host, int port) throws IOException{
    Socket s = new Socket(host,port);

    //Do some book-keeping here ...

    return s;
}
private TreeSet<String> validHosts = null;

@Override
public Socket createSocket(String host, int port) throws IOException{
    Socket s = null;

    try {
        s = new Socket(host,port);
        synchronized(this){
            if(validHosts == null) validHosts = new TreeSet<String>();
            validHosts.add(host);
        }
    } catch (IOException e) {}

    if(s == null && validHosts != null){
        synchronized(this){
            for(String h : validHosts){
                try {
                    s = new Socket(h,port);
                } catch (IOException e) {}
            }
        }
    }

    if(s == null){
        try {
            String h = RemoteServer.getClientHost();
            s = new Socket(RemoteServer.getClientHost(),port);

            synchronized(this){
                if(validHosts == null) validHosts = new TreeSet<String>();
                validHosts.add(h);
            }
        } catch (Exception e) {}
    }

    //No dice - throw an exception:
    if(s == null){
        TreeSet<String> set = new TreeSet<String>();
        set.add(host+"(orig)");

        synchronized(this){
            if(validHosts != null) set.addAll(validHosts);
        }

        StringBuilder sb = new StringBuilder(
            "Could not connect socket on port "+port+
            " to any of the following hosts: ");
        for(String h : set) sb.append(h+" ");

        throw new IOException(sb.toString());
    }

    //Do some book-keeping here ...

    return s;
}
仅当RMI服务器为多主机时有效:

@Override
public Socket createSocket(String host, int port) throws IOException{
    Socket s = new Socket(host,port);

    //Do some book-keeping here ...

    return s;
}
private TreeSet<String> validHosts = null;

@Override
public Socket createSocket(String host, int port) throws IOException{
    Socket s = null;

    try {
        s = new Socket(host,port);
        synchronized(this){
            if(validHosts == null) validHosts = new TreeSet<String>();
            validHosts.add(host);
        }
    } catch (IOException e) {}

    if(s == null && validHosts != null){
        synchronized(this){
            for(String h : validHosts){
                try {
                    s = new Socket(h,port);
                } catch (IOException e) {}
            }
        }
    }

    if(s == null){
        try {
            String h = RemoteServer.getClientHost();
            s = new Socket(RemoteServer.getClientHost(),port);

            synchronized(this){
                if(validHosts == null) validHosts = new TreeSet<String>();
                validHosts.add(h);
            }
        } catch (Exception e) {}
    }

    //No dice - throw an exception:
    if(s == null){
        TreeSet<String> set = new TreeSet<String>();
        set.add(host+"(orig)");

        synchronized(this){
            if(validHosts != null) set.addAll(validHosts);
        }

        StringBuilder sb = new StringBuilder(
            "Could not connect socket on port "+port+
            " to any of the following hosts: ");
        for(String h : set) sb.append(h+" ");

        throw new IOException(sb.toString());
    }

    //Do some book-keeping here ...

    return s;
}
private TreeSet validHosts=null;
@凌驾
公共套接字createSocket(字符串主机,int端口)引发IOException{
套接字s=null;
试一试{
s=新套接字(主机、端口);
已同步(此){
如果(validHosts==null)validHosts=new TreeSet();
validHosts.add(主机);
}
}捕获(IOE){}
如果(s==null&&validHosts!=null){
已同步(此){
for(字符串h:validHosts){
试一试{
s=新插座(h,端口);
}捕获(IOE){}
}
}
}
如果(s==null){
试一试{
字符串h=RemoteServer.getClientHost();
s=新套接字(RemoteServer.getClientHost(),端口);
已同步(此){
如果(validHosts==null)validHosts=new TreeSet();
有效期。添加(h);
}
}捕获(例外e){}
}
//无骰子-抛出异常:
如果(s==null){
树集=新树集();
set.add(主机+“(orig)”);
已同步(此){
if(validHosts!=null)set.addAll(validHosts);
}
StringBuilder sb=新的StringBuilder(
“无法连接端口上的套接字”+端口+
“发送给以下任何主机:”;
对于(字符串h:set)sb.append(h+“”);
抛出新IOException(sb.toString());
}
//在这里做一些簿记。。。
返回s;
}
问题

似乎如果我能以某种方式判断服务器端机器是否是多宿主的,那么我就可以将这两组代码包装在
if(serverIsMultihomed)。。。否则…
这是一种声明。我确实能够在此调用中获取服务器的实际机器名,但调用
InetAddress.getAllByHostName(主机)
实际上不会返回主机的所有IP地址,只返回客户端机器上NIC可见的IP地址。因此,当调用
createSocket(主机、端口)
时,客户端实际上看不到IP地址,这就是我遇到问题的地方。此外,将
java.server.rmi.hostname
设置为我要使用的服务器的IP地址并不能解决此问题,实际上会禁止服务器连接到的不同子网上的机器建立链接


简而言之,有没有其他方法可以从不同的机器上获取所有主机的IP地址,无论是可见的还是其他的,或者我在这里查错了树?

你看了吗?

如果服务器有一个IP地址,每个人都可以看到,这似乎是Sun考虑的唯一的多主机情况,只需在服务器JVM上将java.rmi.server.codebase设置为该地址。根本不需要套接字工厂。

同意,但在我的例子中,我的RMI服务器位于一台在两个不同子网上有IP地址的机器上,但任一子网上的机器都无法相互通信。所以在我的情况下,插座工厂是必要的。RMI是一个很棒的工具,但它不会在遇到缺点时胡乱处理…:/@本·劳里同意了。奇怪的是,整个java.rmi.server.hostname malarkey在很大程度上是不必要的。他们只需将本地套接字地址写入从导出主机出来的存根中。这将解决99%的这种情况,剩下的1%使用java.rmi.server.hostname。我确实在11年前告诉过他们,在邮件列表上,但是有一个人对这件事没有完全考虑清楚的建议非常恼火。你把它钉在了头上。Java开发人员为了在分布式系统中使用RMI而开发RMI时,完全忽略了这一点,这似乎真的很愚蠢。即使是现在,他们也可以修复它,这不会造成任何问题。这样我就可以省下10天的哀号和咬牙切齿。。。