试图连接到RMI注册表,但得到java.net.ConnectException:连接被拒绝:连接



我有两台电脑。其中一个正在运行RMI注册表——它是由以下代码单独创建的:

package main;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;
public class TheRegistry{
    public static void main(String[] args) {
        try {
            Registry reg = LocateRegistry.createRegistry(2020);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally{
            System.out.println("Registry Created");
            Scanner input = new Scanner(System.in);
            input.nextInt();
            System.exit(0);
        }
    }
}

另一台计算机有一个服务器,该服务器试图在此注册表上注册一个对象,但是,它得到一个异常。下面是服务器的代码:

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.*;
public class TextScramblerServer implements TextScramblerInterface 
{
    private static Remote obj; 
    // main method to export
    @Override //Return input text as-is.
    public String testInputText(String inputText) {
        return "Your input text is: " + inputText;
    }
    @Override //Return the string reversed.
    public String reverse(String inputText) {
        String reversedInput = "";
        for(int i=0; i<inputText.length();i++)
        {
            reversedInput=reversedInput+inputText.charAt((inputText.length()-1)-i);
        }
        return "Result: "+reversedInput;
    }
    @Override //Return the string scrambled.
    public String scramble(String inputText) {
        String scrambledInput="";
        for(int i=0; i<inputText.length();i++)
        {
            if(i%2==0)
            {
                scrambledInput=scrambledInput+inputText.charAt(i);
            }
            else
            {
                scrambledInput=inputText.charAt(i)+scrambledInput;
            }
        }
        return "Result: "+scrambledInput;
    }
    public void exportServer() throws Exception {
        System.setSecurityManager(new RMISecurityManager());
        obj = UnicastRemoteObject.exportObject(this, 2022);
        Registry registry = LocateRegistry.getRegistry("132.205.94.50", 2020);
        registry.bind("test", obj);
    }
    public static void main(String[] args) {
        try {
            (new TextScramblerServer()).exportServer();
            System.out.println("Server is up and running");
        }
        catch(Exception e){
            e.printStackTrace();
            try {
                UnicastRemoteObject.unexportObject(obj, true); //close port
            } catch (NoSuchObjectException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    }
}

我一直得到错误:

java.rmi.ConnectException: Connection refused to host: 132.205.94.50; nested exception is: 
    java.net.ConnectException: Connection refused: connect
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
    at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
    at sun.rmi.server.UnicastRef.newCall(Unknown Source)
    at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
    at TextScramblerServer.exportServer(TextScramblerServer.java:57)
    at TextScramblerServer.main(TextScramblerServer.java:62)
Caused by: java.net.ConnectException: Connection refused: connect
    at java.net.DualStackPlainSocketImpl.connect0(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
    at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
    at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
    at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
    at java.net.PlainSocketImpl.connect(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown Source)
    at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown Source)
    ... 7 more
java.rmi.NoSuchObjectException: object not exported
    at sun.rmi.transport.ObjectTable.unexportObject(Unknown Source)
    at java.rmi.server.UnicastRemoteObject.unexportObject(Unknown Source)
    at TextScramblerServer.main(TextScramblerServer.java:68)

我不明白为什么会发生这种情况。我想我已经试过了

我运行了你的代码,在配置了安全策略后,它为我工作了。

你的ConnectionRefused异常表示底层TCP连接无法建立。这是网络问题,不是RMI问题。

尝试在同一台主机上运行服务器和注册表,并使用localhost作为主机名。如果它工作,问题可能是两个主机之间的防火墙问题。

您可以使用telnet对到特定端口的TCP连接进行简单的测试。如果端口没有监听,telnet将给您一个类似的拒绝连接消息。如果端口正在侦听,您将在终端上看到如下内容:

Connected to localhost.
Escape character is '^]'.

Control-C退出会话。

具体的telnet输出可能因操作系统而异,但它们大致相同。

如果是防火墙问题,您将不得不打开端口。这取决于操作系统,但很容易找到。

您的注册表已被垃圾收集,您的IP地址错误,或者它是一个公共IP地址,您没有配置端口转发。

您需要将Registry引用存储在静态对象中以克服垃圾收集,尽管当rmiregistry.exe已经存在时,该程序的目的是什么我完全不明白。

不管怎样,你找错对象了。您只能绑定到在本地主机上运行的RMI Registry。因此,在绑定或解除绑定时,永远不需要使用"localhost"以外的注册表主机名。

您得到NoSuchObjectException的原因是您正在尝试取消导出存根,这是由obj引用的,这是UnicastRemoteObject.exportObject()的结果,它返回存根。参见Javadoc。您需要保存new TextScramblerServer()的结果并取消导出。

相关内容

  • 没有找到相关文章

最新更新