Spec-Zone .ru
спецификации, руководства, описания, API
|
Это учебное руководство показывает, что Вы ступаете, чтобы следовать, чтобы реализовать и использовать пользовательские фабрики сокета с Java™ Удаленный Вызов метода (Java RMI). Пользовательские фабрики сокета могут быть uesd, чтобы управлять, как удаленные вызовы метода передаются на сетевом уровне. Например, они могут использоваться, чтобы установить опции сокета, привязку адреса управления, установление соединения управления (например, потребовать аутентификации), и управлять кодированием данных (например, добавить шифрование или сжатие).
Когда удаленный объект экспортируется, такой как с конструкторами или exportObject
методы java.rmi.server.UnicastRemoteObject
или java.rmi.activation.Activatable
, тогда возможно определить пользовательскую клиентскую фабрику сокета (a java.rmi.server.RMIClientSocketFactory
экземпляр), и пользовательский сервер снабжают фабрику сокетом (a java.rmi.server.RMIServerSocketFactory
экземпляр), чтобы использоваться, передавая удаленные вызовы для того удаленного объекта.
Клиентская фабрика сокета управляет созданием сокетов, используемых, чтобы инициировать удаленные вызовы, и таким образом может использоваться, чтобы управлять, как соединения устанавливаются и тип сокета, чтобы использовать. Фабрика сокета сервера управляет созданием сокетов сервера, используемых, чтобы получить удаленные вызовы, и таким образом может использоваться, чтобы управлять, как к входящим соединениям прислушиваются и принимаются так же как тип сокетов, чтобы использовать для входящих соединений.
Удаленный тупик для удаленного объекта содержит клиентскую фабрику сокета, если таковые вообще имеются, что удаленный объект экспортировался с, и таким образом клиентская фабрика сокета должна быть сериализуемой, и ее код может быть загружен клиентами точно так же как код для тупиковых классов или любого другого сериализуемого объекта, переданного по удаленному вызову.
Есть также a LocateRegistry.createRegistry
метод для того, чтобы экспортировать реестр с пользовательскими фабриками сокета и a LocateRegistry.getRegistry
метод для того, чтобы получить тупик для реестра с пользовательским клиентом снабжает фабрику сокетом.
(Отметьте, что есть также глобальная фабрика сокета для Java RMI, который может быть установлен с setSocketFactory
метод java.rmi.server.RMISocketFactory
. Эта глобальная фабрика сокета используется для того, чтобы создать сокеты, когда удаленный тупик не содержит пользовательскую клиентскую фабрику сокета и для того, чтобы создать сокеты сервера, когда удаленный объект не экспортировался с пользовательской фабрикой сокета сервера.)
У этого учебного руководства есть три части:
Исходный код для этого учебного руководства доступен в следующих форматах:
Много пользователей интересуются безопасной передачей между Java клиенты и серверы RMI, такой как со взаимной аутентификацией и шифрованием. Пользовательские фабрики сокета обеспечивают рычаг для того, чтобы он сделал это. Для получения дополнительной информации см. Используя Java RMI с SSL.ServerSocket
и Socket
.RMIClientSocketFactory
.RMIServerSocketFactory
.ServerSocket
и Socket
В этом примере пользовательская фабрика сокета создает сокеты, которые выполняют простое шифрование XOR и дешифрование. Отметьте, что этот вид шифрования легко дешифровывается хорошо осведомленным криптоаналитиком и только используется здесь, чтобы сохранить пример простым.
Пользовательская реализация сокета XOR включает следующие источники. Сокеты XOR используют специальные потоковые реализации входа и выхода, чтобы обработать XOR-луг данные, записанные или читать из сокета.
RMIClientSocketFactory
XorClientSocketFactory
, реализации java.rmi.server.RMIClientSocketFactory
интерфейс. Клиентская фабрика сокета должна реализовать createSocket
метод, чтобы возвратить approriate клиент снабжает экземпляр сокетом, XorSocket
. Клиентская фабрика сокета должна реализовать java.io.Serializable
взаимодействуйте через интерфейс так, чтобы экземпляры могли быть сериализированы клиентам как часть удаленных тупиков. Также важно реализовать equals
и hashCode
методы так, чтобы Java реализация RMI правильно совместно использовал ресурсы среди удаленных тупиковых экземпляров с эквивалентными клиентскими фабриками сокета.
package examples.rmisocfac; import java.io.*; import java.net.*; import java.rmi.server.*; public class XorClientSocketFactory implements RMIClientSocketFactory, Serializable { private byte pattern; public XorClientSocketFactory(byte pattern) { this.pattern = pattern; } public Socket createSocket(String host, int port) throws IOException { return new XorSocket(host, port, pattern); } public int hashCode() { return (int) pattern; } public boolean equals(Object obj) { return (getClass() == obj.getClass() && pattern == ((XorClientSocketFactory) obj).pattern); } }
RMIServerSocketFactory
XorServerSocketFactory
, реализации java.rmi.server.RMIServerSocketFactory
интерфейс. Фабрика сокета сервера должна реализовать createServerSocket
метод, чтобы возвратить соответствующий сервер снабжает экземпляр сокетом, XorServerSocket
. Фабрика сокета сервера не должна реализовать Serializable
взаимодействуйте через интерфейс, потому что экземпляры фабрики сокета сервера не содержатся в удаленных тупиках. Для фабрики сокета сервера все еще важно реализовать equals
и hashcode
методы так, чтобы Java реализация RMI правильно совместно использовал ресурсы среди удаленных объектов, экспортируемых с эквивалентными фабриками сокета.
package examples.rmisocfac; import java.io.*; import java.net.*; import java.rmi.server.*; public class XorServerSocketFactory implements RMIServerSocketFactory { private byte pattern; public XorServerSocketFactory(byte pattern) { this.pattern = pattern; } public ServerSocket createServerSocket(int port) throws IOException { return new XorServerSocket(port, pattern); } public int hashCode() { return (int) pattern; } public boolean equals(Object obj) { return (getClass() == obj.getClass() && pattern == ((XorServerSocketFactory) obj).pattern); } }
RMIClientSocketFactory
и RMIServerSocketFactory
реализации. Сохраните ссылку на тупик удаленного объекта в Java реестр RMI так, чтобы клиенты могли искать это.RMIServerSocketFactory
чтобы создать сокет сервера, чтобы принять входящие вызовы к удаленному объекту, и это создаст тупик, который содержит пользовательское соответствие RMIClientSocketFactory
. Та клиентская фабрика сокета будет использоваться, чтобы создать соединения, когда удаленные вызовы будут сделаны к удаленному объекту, используя тупик. Этот пример подобен примеру в учебном руководстве, Начинающем Используя Java RMI, но это использует пользовательские фабрики сокета вместо сокетов по умолчанию, используемых Java реализация RMI.
Приложение использует следующий Hello
удаленный интерфейс:
package examples.rmisocfac; public interface Hello extends java.rmi.Remote { String sayHello() throws java.rmi.RemoteException; }Серверное приложение создает удаленный объект, реализовывая
Hello
отдалите интерфейс и экспорт объект использовать пользовательские фабрики сокета, используя java.rmi.server.UnicastRemoteObject.exportObject
метод, который берет пользовательские фабрики сокета в качестве параметров. Затем, это создает локальный реестр и в том реестре, это связывает ссылку на тупик удаленного объекта с именем "Привет". package examples.rmisocfac; import java.io.*; import java.rmi.*; import java.rmi.server.*; import java.rmi.registry.*; public class HelloImpl implements Hello { public HelloImpl() {} public String sayHello() { return "Hello World!"; } public static void main(String args[]) { if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } byte pattern = (byte) 0xAC; try { /* * Create remote object and export it to use * custom socket factories. */ HelloImpl obj = new HelloImpl(); RMIClientSocketFactory csf = new XorClientSocketFactory(pattern); RMIServerSocketFactory ssf = new XorServerSocketFactory(pattern); Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0, csf, ssf); /* * Create a registry and bind stub in registry. * LocateRegistry.createRegistry(2002); Registry registry = LocateRegistry.getRegistry(2002); registry.rebind("Hello", stub); System.out.println("HelloImpl bound in registry"); } catch (Exception e) { System.out.println("HelloImpl exception: " + e.getMessage()); e.printStackTrace(); } } }
Клиентское приложение получает ссылку на реестр, используемый серверным приложением. Это тогда ищет тупик удаленного объекта и вызывает его удаленный метод sayHello
:
package examples.rmisocfac; import java.rmi.*; import java.rmi.registry.*; public class HelloClient { public static void main(String args[]) { if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } try { Registry registry = LocateRegistry.getRegistry(2002); Hello obj = (Hello) registry.lookup("Hello"); String message = obj.sayHello(); System.out.println(message); } catch (Exception e) { System.out.println("HelloClient exception: " + e.getMessage()); e.printStackTrace(); } } }
Есть четыре шага, чтобы скомпилировать и запустить приложение:
rmic
на (дополнительном) классе реализацииШаг 1:
Скомпилируйте удаленный интерфейс, клиент, и классы сервера
javac -d . XorInputStream.java javac -d . XorOutputStream.java javac -d . XorSocket.java javac -d . XorServerSocket.java javac -d . XorServerSocketFactory.java javac -d . XorClientSocketFactory.java javac -d . Hello.java javac -d . HelloClient.java javac -d . HelloImpl.java
Шаг 2:
Выполненный rmic
на (дополнительном) классе реализации
Отметьте: Выполнение rmic
предварительно генерировать тупиковый класс для класса удаленного объекта только требуется, если удаленный объект должен поддерживать пред5.0 клиентов. С этих 5.0 выпусков, если предварительно сгенерированный тупиковый класс для класса удаленного объекта не может быть загружен, когда удаленный объект экспортируется, тупиковый класс удаленного объекта сгенерирован динамически.
rmic -d . examples.rmisocfac.HelloImpl
java -Djava.security.policy=policy examples.rmisocfac.HelloImpl
Вывод сервера должен быть похожим на это:
HelloImpl bound in registry
В другом окне запускают клиентское приложение, удостоверяясь, что классы приложений находятся в пути к классу:
java -Djava.security.policy=policy examples.rmisocfac.HelloClient
Клиент выводил, должен быть похожим на это:
Hello World!
Отметьте: И серверные и клиентские приложения используют файл политики безопасности, который предоставляет полномочия только файлам в пути локального класса (текущий каталог). Серверное приложение нуждается в разрешении, чтобы принять соединения, и и серверные и клиентские приложения нуждаются в разрешении, чтобы сделать соединения. Разрешение java.net.SocketPermission
предоставляется указанной кодовой базе URL, "файл:" URL относительно текущего каталога. Это разрешение предоставляет возможности и принять соединения от и сделать соединения с любым узлом на непривилегированных портах (который является портами> = 1024).
grant codeBase "file:." { permission java.net.SocketPermission "*:1024-", "connect,accept"; };
Отметьте, что, если Вы хотите настроить передачу к реестру также, например, защитить передачу реестра, тогда это может быть сделано, передавая соответствующие пользовательские фабрики сокета к LocateRegistry.createRegistry
и LocateRegistry.getRegstry
вызовы.