这是我在stackoverflow中的第一篇文章,我正在尝试使用RMI实现聊天但是我被卡住了,我避免使用rmiregistry,一切都在localhost上绑定得很好,但我需要它可以从互联网,端口转发,防火墙下来,实际上我可以通过互联网检索一个对象,我已经使用
System.setProperty("java.rmi.server.hostname","ruso.89.x.ignorelist.com");
然后我的NameServer.java绑定到该IP,但是我通过localhost失去了所有访问权限,现在让我解释一下。这是NameServer.java的代码
public class NameServer
{
public static void main (String args [] )
{
String direscucha = "ruso.89.x.ignorelist.com";
int puertonombres = 5000;
try{
System.setProperty("java.rmi.server.hostname", direscucha);
System.setProperty("java.security.policy", "C:\\Users\\Antonio\\Desktop\\DistributedChat\\myServer.policy");
System.setSecurityManager(new RMISecurityManager());
NameService ns = new NameService();
Registry reg=LocateRegistry.createRegistry(puertonombres);
reg.rebind("ns",ns);
while(true){}
}catch(Exception e){
System.out.println(e);
}
}
}
这是我的政策文件:
grant {
permission java.security.AllPermission;
permission java.net.SocketPermission "ruso.89.x.ignorelist.com:*", "connect,resolve,accept";
permission java.net.SocketPermission "localhost:*", "connect,resolve,accept";
permission java.net.SocketPermission "127.0.0.1:*", "connect,resolve,accept";
};
然后我需要ChatServer.java来运行,这需要ns并将自己绑定到它,因此可以找到ChatServer,问题是当我从局域网外部使用它时我可以让服务器运行!但是当我使用localhost时我得到了一个例外
ChatServer.java(Snippet)
public void work ()
{
String direscucha = "ruso.89.x.ignorelist.com";
int puertonombres = 5000;
System.setProperty("java.rmi.server.hostname", direscucha); //Binds to the Public IP
System.setProperty("java.security.policy", "C:\\Users\\Antonio\\Desktop\\DistributedChat\\myClient.policy"); //marca la politica
System.setSecurityManager(new RMISecurityManager()); //Ejecuta el RMISecurityManager
try
{
String[] list = Naming.list("//localhost:5000/"); //Debugging
System.out.println("Tamanyo: "+list.length);
for(int i=0; i<list.length; i++)
System.out.println(list[i]);
NameService_Stub ns = (NameService_Stub) Naming.lookup("rmi://localhost:5000/ns");
ns.rebind (conf.getServerName(), this);
System.out.println("Servidor registrado::");
}
catch (java.rmi.ConnectException e)
{
System.out.println (e);
System.exit(-1);
}
catch (Exception e)
{
System.out.println(e);
System.exit(-1);
}
所以当ServerChat现在注册时,任何用户都可以执行ChatClient.java从NameService中检索ChatServer的名称然后连接,但是还没有得到,因为我无法管理ChatServer工作。我的第一个问题是,在设置hostname属性时,localhost被阻止但是没有提到,之后我虽然可能是路由器NAT的问题,但它可能是吗?
例外:
java.rmi.ConnectException: Connection refused to host: ruso.89.x.ignorelist.com; nested exception is:
java.net.ConnectException: Connection refused: connect
客户端和服务器策略文件完全相同。 使用WireShark查看发生的情况,发送SYN并收到ACK,收到RST。 我已经烧掉了所有的想法,有什么建议吗?
答案 0 :(得分:0)
我使用
获得了这个System.setProperty( “java.rmi.server.hostname”, “ruso.89.x.ignorelist.com”);
然后我的NameServer.java绑定到那个IP
不,不。这是一种常见的误解,但不正确。除非您提供ServerSockets
,否则RMI始终将其RMIServerSocketFactory
绑定到0.0.0.0。 java.rmi.server.hostname
的作用是将其值嵌入存根(基本上不是InetAddress.getLocalHost()
返回的值)。
while(true){}
您不需要通过这样做来吸烟,但您需要将Registry
引用设为静态变量。导出远程对象时RMI启动一个线程,该远程对象将阻止JVM退出,直到您取消导出它。当远程对象被垃圾收集时,自动导出会自动发生,静态引用会阻止它。
Connection拒绝主持人:ruso.89.x.ignorelist.com
这可能意味着您的内部防火墙不允许您向外连接到该主机,即使它是您自己的。或者ruso.89.x.ignorelist.com
在您的网络中有一个不同的,不正确的DNS映射。