远程计算机监控系统.doc
题目 远程计算机监控系统1、 实验目的熟练运用JAVA开发环境及工具、并用JAVA语言编写程序;掌握面向对象的概念;掌握系统功能模块的合理划分,并实现各模块接口的连接;掌握C/S结构的编程方法;掌握Socket编程的基本原理与方法。2、 实验内容1)远程控制模式架构,基于C/S模式;2)远程控制功能实现,开关机,远程监视;3)远程控制安全考虑;4)远程控制实现平台与技巧;5)远程控制软件实现,要求至少能在两台电脑上正常运行;6)界面新颖友好3、 实验过程3.1 Socket通信流程图设计(1) 客户端请求Socket的步骤如下: 建立客户端Socket连接; 得到Socket的读和写的流; 利用流; 关闭流; 关闭Socket。(2) 服务器端Socket要完成以下的基本的步骤: 建立一个服务器Socket并开始监听; 使用accept()方法取得新的连接; 建立输入和输出流; 在已有的协议上产生会话; 关闭客户端流和Socket; 回到或者转到; 关闭服务器Socket。 图 为面向连接的Socket协作流程图3.2 Java事件处理机制设计事件源注册的方法如下: public void addActionListener(ActionListener l) 添加特定的动作,监听接收来自事件源的动作事件,如果l为空,不会产生任何动作。 监听者实现的接口为ActionListener接口,接口ActionListener来自包java.awt.event。在此接口中只有一个方法: public void actionPerformed(ActionEvent e) 当事件对象e发生时,调用此方法。监听者就需要实现这个方法。3.3 多线程机制设计线程存在一个生命周期,由以下方法体现:(1) start()方法:启动一个线程。(2) run()方法:定义该线程的动作。(3) sleep()方法:使线程睡眠一段时间,单位为ms。(4) stop()方法:结束线程生命周期并执行清理工作。 3.3.1 线程类和Runnable接口1. 建立Thread类的子类 class myThread extends Thread .public void start()/启动线程 .public void run()/运行线程. 2. 实现接口Runnable public interface Runnable Runnable接口可以由任意试图实现线程机制的类来实现。接口包含一个run方法。 public void run() 对象实现Runnable接口时,创建一个线程,启动线程导致对象run方法的调用。4、 关键代码及其分析4.1 -ConnectionDialog.java-/* * Title: 目标机器ip输入对话框 */public class ConnectionDialog extends JDialog JPanel panel1 = new JPanel(); BorderLayout borderLayout1 = new BorderLayout(); JTextField address = new JTextField(); JButton ok = new JButton(); public ConnectionDialog(MainFrame owner, String title, boolean modal) super(owner, title, modal); try setDefaultCloseOperation(DISPOSE_ON_CLOSE); jbInit(); catch (Exception exception) exception.printStackTrace(); private void jbInit() throws Exception panel1.setLayout(borderLayout1); ok.setText("确定"); ok.addActionListener(new ConnectionDialog_Ok_actionAdapter(this); setContentPane(panel1); panel1.add(address, java.awt.BorderLayout.CENTER); panel1.add(ok, java.awt.BorderLayout.EAST); setSize(200,50); setMainFrameCenter(this); setResizable(false); /* * 设置弹出窗口显示位置在主窗口中间 */ public static void setMainFrameCenter(JDialog dialog) Point point = dialog.getOwner().getLocation(); Dimension dimension = dialog.getOwner().getSize(); dialog.setLocation(point.x+dimension.width/2-dialog.getSize().width/2, point.y+dimension.height/2-dialog.getSize().height/2);/设置位置 public InetAddress getEnterInetAddress() throws UnknownHostException return InetAddress.getByName(address.getText(); class ConnectionDialog_Ok_actionAdapter implements ActionListener ConnectionDialog adaptee ; public ConnectionDialog_Ok_actionAdapter(ConnectionDialog adaptee) this.adaptee = adaptee; /* * 按下"确定"按钮,开始连接被控端 */ public void actionPerformed(ActionEvent e) InetAddress inet = null; adaptee.setVisible(false); MainFrame main = (MainFrame)adaptee.getOwner(); try main.setEnabled(false); inet = adaptee.getEnterInetAddress(); ControlledStatus client = MainController.Connect(inet);/发送初试化命令 main.setConnection(client); main.setEnabled(true); MainController.startClientScreen(client,main);/开启被控端屏幕监听线程 main.screen.setMainControl(MainController.startControlSocket(client);/开启控制连接 main.screen.setControlledStatus(client); main.jToolBar1.disconnect.setEnabled(true); main.jToolBar1.connect.setEnabled(false); catch(UnknownHostException e1) JOptionPane.showMessageDialog(main,"被控端地址错误!","错误信息",JOptionPane.WARNING_MESSAGE); catch(Exception e2) e2.printStackTrace(); JOptionPane.showMessageDialog(main,e2.getMessage(),"错误信息",JOptionPane.WARNING_MESSAGE); finally adaptee.dispose(); main.setEnabled(true); 4.2-MainFrame.java-public class MainFrame extends JFrame ControlledScreenPanel screen ; JPanel panel ; int flag = 0 ; /0初始显示panel面板 1显示screen面板 MainToolBar jToolBar1 ; public MainFrame() try setDefaultCloseOperation(EXIT_ON_CLOSE); jbInit(); catch (Exception exception) exception.printStackTrace(); private void jbInit() throws Exception screen = new ControlledScreenPanel(); panel = new JPanel(); jToolBar1 = new MainToolBar(this); this.setSize(new Dimension(600, 400); this.setTitle("远程控制系统"); getContentPane().add(jToolBar1, java.awt.BorderLayout.PAGE_START); getContentPane().add(panel,java.awt.BorderLayout.CENTER); this.setFocusable(true); public void switchPanel(int f) switch(f) case 1 : this.remove(panel); screen.bind(this); break ; case 2 : screen.remove(); getContentPane().add(panel,java.awt.BorderLayout.CENTER); break ; this.flag = f ; /* * 显示被控端屏幕 */ public void showClientScreen(BufferedImage image) if (image = null)return; screen.setBufferedImage(image); private ControlledStatus status = null; /被监视端状态信息 private boolean isConnection = false ; /是否连接被控端 public boolean isConnection() return isConnection ; public ControlledStatus getControlledStatus() return status; public void setConnection(ControlledStatus status) this.status = status ; switchPanel(1); setVisible(false);setVisible(true); public void setDisConnection() switchPanel(2) ; this.setSize(new Dimension(600, 400); setVisible(false);setVisible(true); status = null ; 4.3 -MainController.java-public class MainController public static ControlledStatus Connect(InetAddress inet) throws Exception ControlledStatus status = null; ServerSocket server =openNewPort(); Socket socket = null ; try server.setSoTimeout(Environment.TCP_TIME_OUT); sendCommand(inet, CommandHandle.toCommand(CommandHandle.Command_Connection, server.getLocalPort(); socket = server.accept(); ObjectInputStream read = new ObjectInputStream(socket.getInputStream(); Object obj = read.readObject(); if (obj != null) status = (ControlledStatus) obj; status.setControlled(inet); else throw new IOException("连接失败:n 目标机器不可达"); catch (IOException e) throw new Exception("连接失败:n 目标机器不可达"); public static void Disconnect(InetAddress inet) try sendCommand(inet, CommandHandle.toCommand(CommandHandle.Command_Disconnection, ""); catch(IOException e) public static ServerSocket openNewPort()throws IOException ServerSocket socket = null; boolean sucess = true; int count=0; while(sucess) count+; if(count>=10)throw new IOException("连接失败,无法开启本机器端口."); int c=(int)(Math.random()*10000); int port=(int)(c-65530*(c/65530); try socket = new ServerSocket(port); sucess = false; catch (IOException e) continue ; return socket ; public static void sendCommand(InetAddress inet,String command)throws IOException byte sp = command.getBytes(); DatagramPacket packet = new DatagramPacket(sp, sp.length, inet, Environment.UDP_PORT); try DatagramSocket sd = new DatagramSocket(); sd.send(packet); catch (Exception e) throw new IOException("向被控端请求失败!"); public static void startClientScreen(ControlledStatus clientstatus,MainFrame frame) throws Exception ServerSocket server = openNewPort(); server.setSoTimeout(Environment.TCP_TIME_OUT); sendCommand(clientstatus.getControlled(), CommandHandle.toCommand(CommandHandle.Command_Screen,server.getLocalPort(); Socket socket=server.accept(); System.out.println(socket.getRemoteSocketAddress()+ " 已经连接端口:"+socket.getLocalPort()+" 等待进行图形传送"); Class argTypes = new ClassSocket.class,MainFrame.class; Object args = new Objectsocket,frame; ThreadManager.start(ImageReceiveThread.class,argTypes,args); public static MainControlSocket startControlSocket(ControlledStatus clientstatus)throws IOException MainControlSocket control = null ; try ServerSocket server = openNewPort(); server.setSoTimeout(Environment.TCP_TIME_OUT); sendCommand(clientstatus.getControlled(), CommandHandle.toCommand(CommandHandle.Command_Control,server.getLocalPort(); Socket socket=server.accept(); System.out.println(socket.getRemoteSocketAddress()+ " 已经连接端口:"+socket.getLocalPort()+ " 控制套接开启"); control = new MainControlSocket(socket); catch (IOException e) throw new IOException("网络故障"); return control ; class MainControlSocket private Socket socket = null; private ObjectOutputStream out = null; public MainControlSocket(Socket socket) throws IOException this.socket = socket; this.socket.setSendBufferSize(Environment.EVENT_CACHE); out = new ObjectOutputStream(socket.getOutputStream(); 4.5-ControlledWindowResponseThread.java-public class ControlledWindowResponseThread extends ThreadServer private Socket socket ; private ObjectInputStream in ; private Robot action ; private boolean isRun = true; public ControlledWindowResponseThread(Socket socket) throws IOException, AWTException action = new Robot(); this.socket = socket; this.socket.setReceiveBufferSize(Environment.EVENT_CACHE); in = new ObjectInputStream(socket.getInputStream(); public void run() while (isRun) try Object obj = in.readObject(); if (obj != null) handleEvent( (InputEvent) obj); /处理 catch (ClassNotFoundException e) continue; catch (IOException ex) break; try if (in != null) in.close(); in = null; if (socket != null) socket.close(); socket = null; ThreadManager.remove(this.getClass(); catch (Exception e) /*-事件处理-*/ private void handleEvent(InputEvent event) MouseEvent mevent = null ; /鼠标事件 MouseWheelEvent mwevent = null ;/鼠标滚动事件 KeyEvent kevent = null ; /键盘事件 int mousebuttonmask = -100; /鼠标按键 switch (event.getID() case MouseEvent.MOUSE_MOVED : /鼠标移动 mevent = ( MouseEvent )event ; action.mouseMove( mevent.getX() , mevent.getY() ); break ; case MouseEvent.MOUSE_PRESSED : /鼠标键按下 mevent = ( MouseEvent ) event; action.mouseMove( mevent.getX() , mevent.getY() ); mousebuttonmask = getMouseClick( mevent.getButton() ); if(mousebuttonmask != -100) action.mousePress(mousebuttonmask); break; case MouseEvent.MOUSE_RELEASED : /鼠标键松开 mevent = ( MouseEvent ) event; action.mouseMove( mevent.getX() , mevent.getY() ); mousebuttonmask = getMouseClick( mevent.getButton() ); if(mousebuttonmask != -100) action.mouseRelease( mousebuttonmask ); break ; case MouseEvent.MOUSE_WHEEL : /鼠标滚动 mwevent = ( MouseWheelEvent ) event ; action.mouseWheel(mwevent.getWheelRotation(); break ; case MouseEvent.MOUSE_DRAGGED : /鼠标拖拽 mevent = ( MouseEvent ) event ; action.mouseMove( mevent.getX(), mevent.getY() ); break ; case KeyEvent.KEY_PRESSED : /按键 kevent = ( KeyEvent ) event; action.keyPress( kevent.getKeyCode() ); break ; case KeyEvent.KEY_RELEASED : /松键 kevent= ( KeyEvent ) event ; action.keyRelease( kevent.getKeyCode() ); break ; default: break ; /* * 鼠标按键翻译 */ private int getMouseClick(int button) if (button = MouseEvent.BUTTON1) /左键 ,中间键为BUTTON2 return InputEvent.BUTTON1_MASK; if (button = MouseEvent.BUTTON3) /右键 return InputEvent.BUTTON3_MASK; return -100; /* * 鼠标单击 */ public void mouseClick(int mousebuttonmask) action.mousePress(mousebuttonmask); action.mouseRelease(mousebuttonmask); public void quit() isRun = false; 4.5-ImageReceiveThread.java-/* * Title: 图像接收线程 * */public class ImageReceiveThread extends ThreadServer private Socket socket ; private MainFrame frame ; JPEGImageDecoder de = null; BufferedImage image = null; private boolean isRun = true; public ImageReceiveThread(Socket socket,MainFrame frame) throws Exception this.socket = socket ; this.