Java RMI не может подключиться к хосту с внешнего клиента - PullRequest
3 голосов
/ 15 июня 2010

Я давно использую RMI в этом проекте. Я получил клиентскую программу для подключения (помимо прочего) к серверу при запуске его через мою локальную сеть, однако при запуске через Интернет я получаю следующее исключение:

java.rmi.ConnectException: Connection refused to host: (private IP of host machine); nested exception is: 
java.net.ConnectException: Connection timed out: 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.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy1.ping(Unknown Source)
at client.Launcher$PingLabel.runPing(Launcher.java:366)
at client.Launcher$PingLabel.<init>(Launcher.java:353)
at client.Launcher.setupContentPane(Launcher.java:112)
at client.Launcher.<init>(Launcher.java:99)
at client.Launcher.main(Launcher.java:59)

Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(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)
... 12 more

Эта ошибка напоминает мою раннюю реализацию RMI, и я могу получить дословную ошибку, если я запускаю клиент локально без запуска серверной программы. Для меня время ожидания подключения означает проблему с ответом сервера.

Вот инициация клиента:

public static void main(String[] args)
{
    try
    {
        String host = "<WAN IP>";
        Registry registry = LocateRegistry.getRegistry(host, 1099);
        Login lstub = (Login) registry.lookup("Login Server");
        Information istub = (Information) registry.lookup("Game Server");
        new Launcher(istub, lstub);

    }
    catch (RemoteException e)
    {
        System.err.println("Client exception: " + e.toString());
        e.printStackTrace();
    }
    catch (NotBoundException e)
    {
        System.err.println("Client exception: " + e.toString());
        e.printStackTrace();
    }
}

Интересно, что здесь не выдается Remote Exception. Вот инициация сервера:

public static void main(String args[])
{
    try
    {
        GameServer gobj = new GameServer();
        Information gstub = (Information) UnicastRemoteObject.exportObject(
                gobj, 1099);
        Registry registry = LocateRegistry.createRegistry(1099);
        registry.bind("Game Server", gstub);

        LoginServer lobj = new LoginServer(gobj);
        Login lstub = (Login) UnicastRemoteObject.exportObject(lobj, 7099);

        // Bind the remote object's stub in the registry
        registry.bind("Login Server", lstub);

        System.out.println("Server ready");
    }
    catch (Exception e)
    {
        System.err.println("Server exception: " + e.toString());
        e.printStackTrace();
    }
}

Плохая практика с уловом (Исключение е) я знаю, но терпите меня.

До этого этапа я знал, что он отлично работает в локальной сети, здесь происходит исключение в глобальной сети, и это первое место, где метод на сервере называется:

private class PingLabel extends JLabel
{
    private static final long serialVersionUID = 1L;

    public PingLabel()
    {
        super("");
        runPing();
    }

    public void setText(String text)
    {
        super.setText("Ping: " + text + "ms");
    }

    public void runPing()
    {
        try
        {
            PingThread pt = new PingThread();
            gameServer.ping();
            pt.setRecieved(true);
            setText("" + pt.getTime());
        }
        catch (RemoteException e)
        {
            e.printStackTrace();
        }
    }
}

Это ярлык, помещенный на пусковую установку в качестве теста ping. метод ping () в игровом сервере ничего не делает, так как метод null.

Стоит также отметить, что порты 1099 и 7099 перенаправляются на сервер (что должно быть очевидно из трассировки стека).

Кто-нибудь может увидеть что-нибудь, что я пропускаю / делаю неправильно? Если вам нужна дополнительная информация, просто спросите.

РЕДАКТИРОВАТЬ: Я практически уверен, что проблема не имеет ничего общего с настройками моего маршрутизатора. При отключении настроек переадресации портов я получаю немного другую ошибку:

Client exception: java.rmi.ConnectException: Connection refused to host: (-WAN IP NOT LOCAL IP-);

, но отображается как на компьютере, локально подключенном к серверу, так и на удаленном компьютере.

Кроме того, я получил его, чтобы он работал без проблем при подключении сервера напрямую к модему (отключение маршрутизатора. Я могу только заключить, что проблема в настройках моего маршрутизатора, но не могу видеть где (я проверил и дважды проверил страницу переадресации портов). Это единственный ответ, который я могу придумать.

1 Ответ

2 голосов
/ 15 июня 2010

Используете ли вы NAT (преобразование сетевых адресов)?Это типичный случай, если ваша локальная сеть использует немаршрутизируемый адрес за маршрутизатором (например, 10.x или 192.169.x и т. Д.).

В этом случае вам необходимо указать публичный IP-адрес сервера.со следующей опцией,

-Djava.rmi.server.hostname=host_name_or_public_ip
...