Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Работа с сетью > Вызов удаленных методов


Автор: Andyb 14.2.2005, 14:13
Пример создания приложения клиент-сервер, работающего с промощью технологии rmi
(Вот ковырялся, может кому полезно будет).
Программа, которая передаёт снимок рабочего стола сервера клиенту.

Программа-сервер, который создаёт объекты-серверы:
Код

/*
* RemoteScreenServer.java
*
* @author  andrew
*/

import java.rmi.*;
import java.rmi.server.*;

public class RemoteScreenServer {
   
   /** Конструктор */
   public RemoteScreenServer() throws Exception {
       RemoteScreenImpl s1 = new RemoteScreenImpl();
       Naming.rebind("getRemoteScreen", s1);
   }
   
   /**
    * @param args
    */
   public static void main(String[] args) {
       try{
         new RemoteScreenServer();
       }
       catch(Exception e){
           e.printStackTrace();
       }
   }  
}

Удаленный интерфейс:
Код

/**
* RemoteScreen.java
*
* @author  andrew
*/

import java.rmi.*;
import javax.swing.*;

public interface RemoteScreen extends Remote{
   
   ImageIcon getIcon() throws RemoteException;
   
}

Класс-сервер, реализующий этот интерфейс:
Код

/**
* RemoteScreenImpl.java
*
* @author  andrew
*/

import java.rmi.*;
import java.rmi.server.*;
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;

public class RemoteScreenImpl extends UnicastRemoteObject
                                                    implements RemoteScreen {
   private ImageIcon icon;
   private GraphicsEnvironment environment;
   private GraphicsDevice screen;
   private Robot robot;
   private BufferedImage image;
   private Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
   
   /** Конструктор */
   public RemoteScreenImpl() throws RemoteException, AWTException {
       environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
       screen = environment.getDefaultScreenDevice();
       robot = new Robot(screen);
   }
   
   public ImageIcon getIcon() throws RemoteException {
       image = robot.createScreenCapture(new Rectangle(0, 0,
                                        screenSize.width, screenSize.height));
       icon = new ImageIcon(image);
       return icon;
   }
}

Программа-клиент, которая вызывает удаленные методы:
Код

/**
* RemoteScreenClient.java
*
* @author andrew
*/

import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.rmi.*;
import java.rmi.server.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class RemoteScreenClient
{  
  private static String url = "rmi://localhost/";//или адрес удаленной машины
  private static JLabel imageLabel = new JLabel();
 
  public static void main(String[] args)
  {  
     System.setProperty("java.security.policy", "client.policy");
     System.setSecurityManager(new RMISecurityManager());
     JFrame f = new JFrame("Remote Screen:"+url);
     JToolBar toolBar = new JToolBar();
     JButton b = new JButton("View");
     toolBar.add(b);
     b.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
             view();
         }
     });
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     JScrollPane scrollPane = new JScrollPane(imageLabel);
     f.getContentPane().add(scrollPane,BorderLayout.CENTER);
     f.getContentPane().add(toolBar,BorderLayout.NORTH);
     f.setSize(600, 440);
     f.setLocationRelativeTo(null);
     f.setVisible(true);
  }
 
   private static void view(){
     try{  
        RemoteScreen remoteScreen = (RemoteScreen)Naming.lookup(url +
                                                           "getRemoteScreen");
        imageLabel.setIcon(remoteScreen.getIcon());
     }
     catch(Exception e){  
        e.printStackTrace();
     }
  }
}

Файл политики безопасности(должен находится в каталоге программы):
Код

grant
{  
  permission java.net.SocketPermission
     "*:1024-65535", "connect,accept";
  permission java.net.SocketPermission
     "localhost:80", "connect";
};

Запуск:
1. Компилируем всё.
2. Генерируем класс-заглушку: rmic -v1.2 RemoteScreenImpl
3. Запускаем RMI-реестр:
rmiregistry & (для UNIX)
start rmiregistry (для Windows)
4. Запускаем объект-сервер:
java RemoteScreenServer (для UNIX)
start java RemoteScreenServer (для Windows)
5. Запускаем объект-клиент:
java RemoteScreenClient

Результат:
При нажатии кнопки "View" в появившемся окне вы увидите снимок рабочего стола удаленной(или вашей(если запускаете на одной машине)) машины.

Надеюсь, что кому-нибудь данный пример будет полезен.
AndyB
Добавлено @ 14:20
P.S. Только вот с Java Версии 1.5.0_01 работать не хочет smile

Автор: Domestic Cat 15.2.2005, 06:40
Спасибо, правда аналогичное в факе есть уже smile Было б хорошо разобраться с 1.5 проблемой - что там происходит?

Автор: Andyb 15.2.2005, 09:00
Код
java.rmi.ConnectIOException: error during JRMP connection establishment; nested
exception is:
       java.net.SocketTimeoutException: Read timed out
       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.lookup(Unknown Source)
       at java.rmi.Naming.lookup(Unknown Source)
       at RemoteScreenClient.view(RemoteScreenClient.java:44)
       at RemoteScreenClient.access$000(RemoteScreenClient.java:15)
       at RemoteScreenClient$1.actionPerformed(RemoteScreenClient.java:30)
       at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
       at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
       at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
       at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
       at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Sour
ce)
       at java.awt.Component.processMouseEvent(Unknown Source)
       at javax.swing.JComponent.processMouseEvent(Unknown Source)
       at java.awt.Component.processEvent(Unknown Source)
       at java.awt.Container.processEvent(Unknown Source)
       at java.awt.Component.dispatchEventImpl(Unknown Source)
       at java.awt.Container.dispatchEventImpl(Unknown Source)
       at java.awt.Component.dispatchEvent(Unknown Source)
       at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
       at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
       at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
       at java.awt.Container.dispatchEventImpl(Unknown Source)
       at java.awt.Window.dispatchEventImpl(Unknown Source)
       at java.awt.Component.dispatchEvent(Unknown Source)
       at java.awt.EventQueue.dispatchEvent(Unknown Source)
       at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)

       at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
       at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
       at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
       at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.net.SocketTimeoutException: Read timed out
       at java.net.SocketInputStream.socketRead0(Native Method)
       at java.net.SocketInputStream.read(Unknown Source)
       at java.io.BufferedInputStream.fill(Unknown Source)
       at java.io.BufferedInputStream.read(Unknown Source)
       at java.io.DataInputStream.readByte(Unknown Source)
       ... 32 more

Примерно тоже самое с серверами TCP и UDP - на версии 1.5 работать отказываются(либо вылетают по таймауту, либо вообще отказываются запускаться).
Из-за этого даже пришлось повременить с переводом рабочих проектов на версию 1.5 smile

Автор: Domestic Cat 15.2.2005, 09:10
Попробую на 1.5 посмотреть сейчас. А ось какая, не линух случаем?

Автор: Andyb 15.2.2005, 09:15
WinXPProfSP2 И Win Server 2003

Автор: Domestic Cat 15.2.2005, 09:31
Все работает - 1.5.0, масдай 2000 про.
Кстати исправь как запускать клиента - RemoteScreenClient.

Автор: Andyb 15.2.2005, 10:02
Исправил...
Проблема в XPSP2

Автор: Domestic Cat 15.2.2005, 10:26
Ок, поместил в ФАК smile

Автор: djGri 8.3.2005, 08:41
Цитата(Andyb @ 15.2.2005, 08:00)
at sun.rmi.server.UnicastRef.newCall(Unknown Source)
      at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)

Это потому-что у клиента нет файла RegistryImpl_Stub

после компиляции надо сделать rmic RemoteScreenImpl , oн создаст RegistryImpl_Stub , который надо переписать клиенту

Автор: Guest 8.3.2005, 21:36
Цитата(Andyb @ 14.2.2005, 14:13)
3. Запускаем RMI-реестр:
rmiregistry & (для UNIX)
start rmiregistry (для Windows)

можно запустить из программы:
Код

server obj = new server ();
     Registry registry = LocateRegistry.createRegistry(1099); // 1099 = default, но можно поменять
  registry.rebind ("MyServer", obj);

Автор: Andyb 9.3.2005, 13:18
Цитата
Это потому-что у клиента нет файла RegistryImpl_Stub
после компиляции надо сделать rmic RemoteScreenImpl , oн создаст RegistryImpl_Stub , который надо переписать клиенту

to djGri:
все там есть(см.п.2 исх.сообщ), проблема в WinXPSP2 - это доказано и подтверждено фактами!
to Guest:
Цитата

можно запустить из программы:
...

Спасибо - очень полезная информация

Автор: v2v 6.11.2007, 14:11
что то у меня и в j2sdk1.4.1_02 не хочет запускатся .Ошибка таже нету *_Stub хотя он лежит в папке. (правда на компьютере установлена 5 джавка).

Автор: Nex 7.1.2008, 16:39
Цитата(Andyb @  9.3.2005,  13:18 Найти цитируемый пост)
все там есть(см.п.2 исх.сообщ), проблема в WinXPSP2 - это доказано и подтверждено фактами!


Так что никто не в курсе как этот баг с SP2 обойти?..

Автор: Andyb 7.1.2008, 17:31
брандмауэр отключить полностью, и если у тебя NOD32 в нем прописать  для java.exe разрешения

Автор: Nex 7.1.2008, 17:58
сервис брандмауэра отключен, антивирус - веб, его отключение не помогло :(

Автор: Nex 8.1.2008, 00:28
Все работает, это я тупил. Интрефейсы на клиенте и на сервере были немного разные... 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)