Поскольку я не хотел реализовывать протокол связи для своего приложения на основе клиент-сервер, я реализовал клиент RMI и сервер RMI с обеих сторон для обмена информацией между этими двумя компонентами.Как мне настроить среду RMI, чтобы я мог использовать ее в «реальной» сети?
Если я попытаюсь использовать свое приложение, запустив два компонента на одном компьютере, все работает нормально. Но если я разбиваю компоненты на два разных компьютера (Kubuntu 9.04 внутри как виртуальная машина в среде Windows 7 RC с отключенным брандмауэром и родной средой Ubuntu 9.04), похоже, что клиент RMI не может выполнять методы, которые определенных на стороне сервера. (Каждый вызов функции приводит к исключению RMI.)
В настоящее время я установил системное свойство «java.rmi.server.hostname» с обеих сторон на сетевой интерфейс, который должен использоваться для обмена данными и зарегистрирован по умолчанию порт для связи с демоном rmi (?) rmid.
Есть ли у кого-нибудь идеи, что может произойти неправильно? Должен ли я устанавливать некоторые другие параметры, такие как «java.rmi.server.codebase» (http://java.sun.com/j2se/1.4.2/docs/guide/rmi/javarmiproperties.html), чтобы иметь возможность использовать функциональность RMI в моем приложении?
Edit: Хорошо, вот некоторая дополнительная информация для вас:
В фазе инициализации мой клиент пытается установить соединение с сервером RMI серверного компонента, который был инициализирован с помощью следующих двух методов:
private void initialize()
{
// set ip address of rmi server
System.setProperty("java.rmi.server.hostname", ipAddress);
// try to register rmi server
try
{
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
}
catch (Exception e)
{
// ignore
}
}
public void start()
{
System.out.print("starting master control RMI server ...");
try
{
Naming.rebind("MasterControl", this);
}
catch (Exception e)
{
System.out.println("error: could not initialize master control RMI server");
System.exit(1);
}
// set running flag
isRunning = true;
System.out.println(" done");
}
«ipAddress» - это IP-адрес сетевого интерфейса серверного компонента.
Метод, который используется клиентским компонентом для установления соединения выглядит следующим образом:
public void connect()
{
// build connection url
String url = "rmi://" + masterControlIpAddress + "/MasterControl";
System.out.println(url);
System.out.print("connecting to master control ...");
// try to connect to master control server
while (connection == null)
{
try
{
connection = (MasterControlInterface) Naming.lookup(url);
id = connection.register(localIpAddress);
}
catch (Exception e)
{
// ignore
}
if (connection == null)
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
System.out.println(" done");
}
Как вы можете видеть, что мой клиент вызывает функцию, чтобы зарегистрировать соединение на сервере:
@Override
public int register(String ipAddress) throws RemoteException
{
// add connection to registrationHandler
masterControl.registrationHandler.addConnection(ipAddress);
// log
int connectionCount = masterControl.registrationHandler.getConnectionCount();
System.out.println("slave control (" + ipAddress + ") instance has been registered at the master control server under the following id: " + connectionCount);
return connectionCount;
}
Если я запускаю свою программу с использованием реального сетевого соединения, текст «подчиненный элемент управления ...» не отображается на стороне сервера. Поэтому я не уверен, если функция действительно вызвана клиентским компонентом.
После того, как клиентский компонент происходит инициализация пытается уведомить компонент сервера, вызвав следующий метод, используя его RMI подключения к серверу:
public void sendInitializationDone()
{
try
{
connection.initializationDone();
}
catch (RemoteException e)
{
System.out.println("error: could not send 'initializationDone' message to master control");
System.out.println(e);
System.exit(1);
}
}
установить флаг на стороне сервера.
Ошибка внутри этой встречается, функции на стороне клиента:
java.rmi.ConnectException: Соединение отказался принять 127.0.1.1; Вложенное исключение: java.net.ConnectException: соединение отклонено.
Я понятия не имею, почему хозяин находится здесь 127.0.1.1 ...
@nos
Конечно, я отключил брандмауэр Windows и защиты mechanismn в Kaspersky Internet Security. Я не думаю, что в моем Kubuntu работает брандмауэр.В общем случае можно установить соединение, потому что я уже использовал scp для копирования моей программы на другую машину.
Edit2:
Mhhh, после установки записи в/и т.д./хостов, который относится к машине с IP-адресом машины, кажется, работает, но на самом деле не понимаю, почему это делает ...
BR,
Markus
Исключение RMI было бы приятно видеть. –
Прежде всего, вставьте исключение, которое вы получите, так как это скажет, что не удается. Я предполагаю, что вы уже подтвердили, что у вас есть базовая сеть между хостом и виртуальной машиной? Убедитесь, что kubuntu и машина Windows не настроены с помощью какого-либо брандмауэра. – nos
Думаю, нам нужна дополнительная информация. –