Java 本地主机拒绝 Rmi 连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1823305/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 23:00:05  来源:igfitidea点击:

Rmi connection refused with localhost

javaconnectionlocalhostrmi

提问by Fortega

I have a problem using java rmi:

我在使用 java rmi 时遇到问题:

When I'm trying to run my server, I get a connectException (see below).

当我尝试运行我的服务器时,我收到一个 connectException(见下文)。

Exception happens when executing the rebind method:

执行 rebind 方法时发生异常:

Runtime.getRuntime().exec("rmiregistry 2020");
MyServer server = new MyServer();
Naming.rebind("//localhost:2020/RemoteDataPointHandler", server);

when using rmi://localhost:2020/RemoteDataPointHandler instead, it doesn't work either. Also using the default port does not work. I also tried using the 127.0.0.1 ip-address, but with the same effect.

当使用 rmi://localhost:2020/RemoteDataPointHandler 时,它也不起作用。使用默认端口也不起作用。我也尝试使用 127.0.0.1 ip-address,但效果相同。

my runtime args:

我的运行时参数:

-Djava.security.policy=java.security.AllPermission
Exception in thread "main" java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: 
    java.net.ConnectException: Connection refused
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)
    at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
    at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
    at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
    at java.rmi.Naming.rebind(Naming.java:160)
    at be.fortega.knx.server.Main.(Main.java:25)
    at be.fortega.knx.server.Main.main(Main.java:16)
Caused by: java.net.ConnectException: Connection refused
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:433)
    at java.net.Socket.connect(Socket.java:524)
    at java.net.Socket.connect(Socket.java:474)
    at java.net.Socket.(Socket.java:371)
    at java.net.Socket.(Socket.java:184)
    at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
    at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569)
    ... 7 more

采纳答案by Fortega

It seems to work when I replace the

当我更换

Runtime.getRuntime().exec("rmiregistry 2020");

by

经过

LocateRegistry.createRegistry(2020);

anyone an idea why? What's the difference?

有人知道为什么吗?有什么不同?

回答by Steen

You need to have a rmiregistryrunning before attempting to connect (register) a RMI service with it.

rmiregistry在尝试连接(注册)RMI 服务之前,您需要运行它。

The LocateRegistry.createRegistry(2020)method call creates and exports a registry on the specified port number.

LocateRegistry.createRegistry(2020)方法调用创建和出口上的指定端口号的注册表。

See the documentation for LocateRegistry

请参阅LocateRegistry的文档

回答by AxelTheGerman

had a simliar problem with that connection exception. it is thrown either when the registry is not started yet (like in your case) or when the registry is already unexported (like in my case).

该连接异常有一个类似的问题。它在注册表尚未启动时(如您的情况)或注册表已未导出(如我的情况)时抛出。

but a short comment to the difference between the 2 ways to start the registry:

但对启动注册表的两种方法之间的区别的简短评论:

Runtime.getRuntime().exec("rmiregistry 2020");

runs the rmiregistry.exe in javas bin-directory in a new process and continues parallel with your java code.

在新进程中运行 javas bin 目录中的 rmiregistry.exe 并继续与您的 java 代码并行。

LocateRegistry.createRegistry(2020);

the rmi method call starts the registry, returns the reference to that registry remote object and then continues with the next statement.

rmi 方法调用启动注册表,返回对该注册表远程对象的引用,然后继续执行下一条语句。

in your case the registry is not started in time when you try to bind your object

在您的情况下,当您尝试绑定对象时,注册表未及时启动

回答by user1008532

One difference we can note in Windows is:

我们可以在 Windows 中注意到的一个区别是:

If you use Runtime.getRuntime().exec("rmiregistry 1024");

如果你使用 Runtime.getRuntime().exec("rmiregistry 1024");

you can see rmiregistry.exe process will run in your Task Manager

您可以看到 rmiregistry.exe 进程将在您的任务管理器中运行

whereas if you use Registry registry = LocateRegistry.createRegistry(1024);

而如果你使用 Registry registry = LocateRegistry.createRegistry(1024);

you can not see the process running in Task Manager,

您无法在任务管理器中看到正在运行的进程,

I think Java handles it in a different way.

我认为 Java 以不同的方式处理它。

and this is my server.policy file

这是我的 server.policy 文件

Before running the the application, make sure that you killed all your existing javaw.exe and rmiregistry.exe corresponds to your rmi programs which are already running.

在运行应用程序之前,请确保您杀死了所有现有的 javaw.exe 和 rmiregistry.exe 对应于您已经运行的 rmi 程序。

The following code works for me by using Registry.LocateRegistry()or

以下代码适用于我使用Registry.LocateRegistry()

Runtime.getRuntime.exec("");


// Standard extensions get all permissions by default

grant {
    permission java.security.AllPermission;
};

VM argument

虚拟机参数

-Djava.rmi.server.codebase=file:\C:\Users\Durai\workspace\RMI2\src\

Code:

代码:

package server;    

import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.Remote;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class HelloServer 
{
  public static void main (String[] argv) 
  {
    try {

        if(System.getSecurityManager()==null){
            System.setProperty("java.security.policy","C:\Users\Durai\workspace\RMI\src\server\server.policy");
            System.setSecurityManager(new RMISecurityManager());
        }

 Runtime.getRuntime().exec("rmiregistry 1024");

 //     Registry registry = LocateRegistry.createRegistry(1024);
   //   registry.rebind ("Hello", new Hello ("Hello,From Roseindia.net pvt ltd!"));
   //Process process = Runtime.getRuntime().exec("C:\Users\Durai\workspace\RMI\src\server\rmi_registry_start.bat");

        Naming.rebind ("//localhost:1024/Hello",new Hello ("Hello,From Roseindia.net pvt ltd!")); 
      System.out.println ("Server is connected and ready for operation.");
    } 
    catch (Exception e) {
      System.out.println ("Server not connected: " + e);
      e.printStackTrace();
    }
  }
}

回答by user1613007

it seems that you should set your command as an String[],for example:

似乎您应该将命令设置为String[],例如:

String[] command = new String[]{"rmiregistry","2020"};
Runtime.getRuntime().exec(command);

it just like the style of main(String[] args).

它就像main(String[] args).