Explorar o código

java实现远程控制

朱丽 %!s(int64=4) %!d(string=hai) anos
achega
7321f9926f
Modificáronse 30 ficheiros con 846 adicións e 0 borrados
  1. 2 0
      .idea/.gitignore
  2. 13 0
      .idea/artifacts/Java_war_exploded.xml
  3. 6 0
      .idea/misc.xml
  4. 8 0
      .idea/modules.xml
  5. 124 0
      .idea/uiDesigner.xml
  6. 6 0
      .idea/vcs.xml
  7. 23 0
      Java实现远程控制.iml
  8. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/becontroller/RemoteComputer.class
  9. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/controller/Controller$1.class
  10. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/controller/Controller$2.class
  11. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/controller/Controller$3.class
  12. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/controller/Controller$4.class
  13. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/controller/Controller.class
  14. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/controller/MyException.class
  15. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/controller/Server$1.class
  16. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/controller/Server$2.class
  17. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/controller/Server$3.class
  18. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/controller/Server.class
  19. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/thread/CaptureThread.class
  20. BIN=BIN
      out/production/Java实现远程控制/com/sziit/G06/thread/EventReadThread.class
  21. BIN=BIN
      saved.jpg
  22. 0 0
      screenImg”+i+”.jpeg
  23. 54 0
      src/com/sziit/G06/becontroller/RemoteComputer.java
  24. 210 0
      src/com/sziit/G06/controller/Controller.java
  25. 19 0
      src/com/sziit/G06/controller/MyException.java
  26. 164 0
      src/com/sziit/G06/controller/Server.java
  27. 89 0
      src/com/sziit/G06/thread/CaptureThread.java
  28. 106 0
      src/com/sziit/G06/thread/EventReadThread.java
  29. 6 0
      web/WEB-INF/web.xml
  30. 16 0
      web/index.jsp

+ 2 - 0
.idea/.gitignore

@@ -0,0 +1,2 @@
+# Default ignored files
+/workspace.xml

+ 13 - 0
.idea/artifacts/Java_war_exploded.xml

@@ -0,0 +1,13 @@
+<component name="ArtifactManager">
+  <artifact type="exploded-war" name="Java实现远程控制:war exploded">
+    <output-path>$PROJECT_DIR$/out/artifacts/Java_war_exploded</output-path>
+    <root id="root">
+      <element id="javaee-facet-resources" facet="Java实现远程控制/web/Web" />
+      <element id="directory" name="WEB-INF">
+        <element id="directory" name="classes">
+          <element id="module-output" name="Java实现远程控制" />
+        </element>
+      </element>
+    </root>
+  </artifact>
+</component>

+ 6 - 0
.idea/misc.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8.0_191" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/Java实现远程控制.iml" filepath="$PROJECT_DIR$/Java实现远程控制.iml" />
+    </modules>
+  </component>
+</project>

+ 124 - 0
.idea/uiDesigner.xml

@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Palette2">
+    <group name="Swing">
+      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+      </item>
+      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
+        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+        <initial-values>
+          <property name="text" value="Button" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="RadioButton" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="CheckBox" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="Label" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+          <preferred-size width="-1" height="20" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+      </item>
+    </group>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 23 - 0
Java实现远程控制.iml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="web" name="Web">
+      <configuration>
+        <descriptors>
+          <deploymentDescriptor name="web.xml" url="file://$MODULE_DIR$/web/WEB-INF/web.xml" />
+        </descriptors>
+        <webroots>
+          <root url="file://$MODULE_DIR$/web" relative="/" />
+        </webroots>
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/becontroller/RemoteComputer.class


BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/controller/Controller$1.class


BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/controller/Controller$2.class


BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/controller/Controller$3.class


BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/controller/Controller$4.class


BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/controller/Controller.class


BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/controller/MyException.class


BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/controller/Server$1.class


BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/controller/Server$2.class


BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/controller/Server$3.class


BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/controller/Server.class


BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/thread/CaptureThread.class


BIN=BIN
out/production/Java实现远程控制/com/sziit/G06/thread/EventReadThread.class


BIN=BIN
saved.jpg


+ 0 - 0
screenImg”+i+”.jpeg


+ 54 - 0
src/com/sziit/G06/becontroller/RemoteComputer.java

@@ -0,0 +1,54 @@
+package com.sziit.G06.becontroller;
+
+import com.sziit.G06.thread.CaptureThread;
+import com.sziit.G06.thread.EventReadThread;
+import java.awt.*;
+import java.io.*;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+/*
+被控端(客户端):
+1.打开一个端口,发送请求到服务端,表明需要连接的控制端。
+2.连接到控制端,不断的截取屏幕截图传输到控制端。
+3.接受从控制端发送过来的键盘、鼠标事件,实现事件回放。
+*/
+
+public class RemoteComputer extends Thread {
+
+    private DataOutputStream output;
+    private ObjectInputStream input;
+    private ServerSocket server;
+    private Socket socket;
+
+    /**
+     * 首先建立一个ServerSocket对象等待控制端来连接。
+     * 连接成功得到对象输入流和输出流;
+     * 抓取屏幕传回控制端,由线程CaptureThread实现;
+     * 读控制端事件并回放,由线程EventReadThread实现;
+     */
+    public static void main(String[] args) throws IOException {
+
+        //1.建立一个ServerSocket对象等待控制端来连接。
+        System.out.println("等待连接.....");
+        ServerSocket server = new ServerSocket(5209);
+
+        //2.连接成功得到对象输入流和输出流;
+        Socket socket = server.accept();
+        System.out.println("成功连接上...\n"+socket);
+
+        ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
+        DataOutputStream output=new DataOutputStream(socket.getOutputStream());
+
+       //3.抓取屏幕传回控制端,由线程CaptureThread实现;
+        try {
+            new CaptureThread(output).start();
+        } catch (AWTException e) {
+            e.printStackTrace();
+        }
+
+        //4.读控制端事件并回放,由线程EventReadThread实现;
+        new EventReadThread(input).start();//读控制端事件并回放
+    }
+
+}

+ 210 - 0
src/com/sziit/G06/controller/Controller.java

@@ -0,0 +1,210 @@
+package com.sziit.G06.controller;
+
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+ *控制端(对客户端进行远程):
+ * 1.连接被控端,进行控制。
+ * 2.接收从被控端发送过来的屏幕截图,实现在当前窗口的画面回放。
+ * 3.把对控制端的操作(键盘事件、鼠标事假)发送到控制端。
+ */
+
+public class Controller extends Thread {
+
+    private java.io.DataInputStream dis;//读视频流对象
+    private java.io.ObjectOutputStream ous;//写事件流
+    private javax.swing.JLabel la_image = new javax.swing.JLabel();
+
+    /*
+     * 显示页面
+     */
+    public void showUI() {
+        //1.处理图形页面
+        javax.swing.JFrame frame=new javax.swing.JFrame("远程控制");
+        frame.setSize(1920,1080);
+        frame.setResizable(false);
+        la_image.setSize(1920, 1080);
+        JLayeredPane jlp = new JLayeredPane();
+        jlp.add(la_image);
+
+        frame.setLayeredPane(jlp);
+        //设置可见
+        frame.setVisible(true);
+        //控制台退出模式
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        //设置置顶
+        frame.setAlwaysOnTop(true);
+
+        //2.监听键盘事件并处理
+        frame.addKeyListener(new KeyAdapter(){
+                                 public void keyPressed(KeyEvent e) {
+                                     sendEventObject(e);
+                                 }
+                                 @Override
+                                 public void keyReleased(KeyEvent e) {
+                                     sendEventObject(e);
+                                 }
+            @Override
+            public void keyTyped(KeyEvent e) {
+            }
+        });
+        //3.监听鼠标转轮事件并处理
+        frame.addMouseWheelListener(new MouseWheelListener(){
+            public void mouseWheelMoved(MouseWheelEvent e) {
+                sendEventObject(e);
+            }
+        });
+
+
+
+        //4.监听鼠标移动
+        frame.addMouseMotionListener(new MouseMotionListener(){
+            public void mouseDragged(MouseEvent e) {
+                sendEventObject(e);
+            }
+            public void mouseMoved(MouseEvent e) {
+                sendEventObject(e);
+            }
+        });
+
+        //5.监听鼠标按键
+        frame.addMouseListener(new MouseListener(){
+            public void mouseClicked(MouseEvent e) {
+                sendEventObject(e);
+            }
+            public void mouseEntered(MouseEvent e) {
+                sendEventObject(e);
+            }
+            public void mouseExited(MouseEvent e) {
+                sendEventObject(e);
+            }
+            public void mousePressed(MouseEvent e) {
+                sendEventObject(e);
+            }
+            public void mouseReleased(MouseEvent e) {
+                sendEventObject(e);
+            }
+        });
+    }
+//连接服务端
+    private void connectToServer(String ip,int port)
+            throws Exception{
+
+        java.net.Socket sc=new java.net.Socket(ip,port);
+//得到输入流,读取图片数据
+        dis=new DataInputStream(sc.getInputStream());
+//得到输出流,发送事件对象
+        ous=new ObjectOutputStream(sc.getOutputStream());
+
+        if(dis==null||ous==null)throw new MyException("远程控制不接受或未接受被控制。。。");
+
+    }
+     //将控制端所侦听到的事件封装成InputEvent类,用对象输出流发送到被控制端。
+
+    //发送事件对象到被控制端
+    private void sendEventObject(java.awt.event.InputEvent event){
+        try{
+            ous.writeObject(event);
+
+        }catch(Exception ef){
+
+            ef.printStackTrace();
+        }
+
+    }
+
+    public void run(){
+
+        try{
+            //读取图片数据
+            while(true){
+             //图片长度
+                int len=dis.readInt();
+                //把数据储存在字节数组
+                byte[] data=new byte[len];
+                //读取数据输出流中的图片数据
+                dis.readFully(data);
+
+                //通过输入流,以javax.io.ImagIO转成数组,读取图片数据
+                ByteArrayInputStream bins=new ByteArrayInputStream(data);
+                BufferedImage image= ImageIO.read(bins);
+
+               //将读到的数据生成为一个图标对象
+                javax.swing.ImageIcon ic=new ImageIcon(image);
+                Image img = ic.getImage();
+
+                // 2.根据屏幕设定图片的大小
+                Toolkit tk = Toolkit.getDefaultToolkit() ;
+                Dimension d =tk.getScreenSize();
+
+                int w = d.width;
+                int h =d.height;
+
+                //将读取到的图片回放
+                BufferedImage bi = resize(img,1920,1080);
+
+                la_image.setIcon(new ImageIcon(bi));
+
+                la_image.repaint();//销掉以前画的背景
+            }
+        }catch(Exception ef){
+            System.out.println("网络故障:无法读出远程图片数据。。。");
+            ef.printStackTrace();
+        }
+
+    }
+
+//从被控制端传输的图片在控制端实现回放
+    private static BufferedImage resize(Image img, int newW, int newH) {
+//设置在控制端回放的图片大小
+        int w = img.getWidth(null);
+        int h = img.getHeight(null);
+
+        BufferedImage dimg = new BufferedImage(newW, newH,BufferedImage.TYPE_INT_BGR);
+
+        Graphics2D g = dimg.createGraphics();
+        //Graphics2D属于Graphics 类,
+       // 提供了对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制。
+        // 它是用于在 Java(tm) 平台上呈现二维形状、文本和图像的基础类。
+
+        //设置模式
+        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+
+        //按比例缩放图片
+        g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
+        g.dispose();
+        return dimg;
+
+    }
+
+    /**
+     * 1.创建对象
+     * 2.建立显示界面,showUI()实现
+     * 3.连接被控端,私有方法connectToServer(ip,port)实现
+     * 4.启动线程,start()方法
+     *
+     * @param
+     * @throws Exception
+     */
+
+    public static void connect(String ip,int port) throws Exception{
+        //1.创建对象
+        Controller ct=new Controller();
+        //2.建立显示界面,showUI()实现
+        ct.showUI();
+        //3.连接被控端,私有方法connectToServer(ip,port)实现
+        ct.connectToServer(ip,port);
+        //4.启动线程,start()方法
+        ct.start();
+    }
+
+}
+
+

+ 19 - 0
src/com/sziit/G06/controller/MyException.java

@@ -0,0 +1,19 @@
+package com.sziit.G06.controller;
+
+import javax.swing.*;
+
+//定义异常提示
+public class MyException extends RuntimeException {
+
+public String info= "";
+
+public MyException(String info){
+
+        this.info = info;
+
+        System.out.println(info);
+
+        JOptionPane.showMessageDialog(null, this.info,"提示",JOptionPane.ERROR_MESSAGE);
+
+        }
+}

+ 164 - 0
src/com/sziit/G06/controller/Server.java

@@ -0,0 +1,164 @@
+/*
+项目介绍:
+    *Java 实现远程控制:
+        控制端(Controller)、被控端 (RemoteComputer)相当于客户端 ,服务端(Server) 相当于服务端。
+        被控端 (RemoteComputer) 打开一个端口通过服务端等待控制端(Controller)来连接,
+        Server 实现服务端监视界面,当有客户端请求连接后,开启一个线程负责和它通讯。
+        一旦连接成功,被控端(RemoteComputer)不断截取屏幕通过图片传输线程(CaptureThread)发送到控制端(Controller),
+        控制端控制的过程实际上就是操作键盘和鼠标的过程,因此控制端会把键盘和鼠标事件
+        通过事件读取线程(EventReadThread)发送到被控制端 (RemoteComputer),
+        被控制端接收到事件后回放,就起到被控制的效果。
+
+        最终实现实用性:多个客户机通过服务端(Client)实现远程控制。
+ */
+
+package com.sziit.G06.controller;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.Socket;
+
+
+public class Server extends JFrame {
+
+/*
+* (服务端):
+* 实现服务端监视界面,当有客户端请求连接后,开启一个线程负责和它通讯。
+* 接受从被控端发出的请求,根据端口指定对应的线程执行其要求连接的对象与其通讯。
+* */
+
+
+    private static final long serialVersionUID = 1L;
+    private JTextField enterField;
+    private JTextArea displayArea;
+    private ObjectOutputStream output;
+    private ObjectInputStream input;
+    private Socket client;
+    private String chatServer;
+    private String message;
+
+    /*
+    生成服务端通讯界面。
+    */
+
+    //设置文本框的大小
+    public JTextField iptf  =new JTextField(10);
+
+    public JTextField porttf  =new JTextField(3);
+//添加连接与断开按钮
+    public JButton jb1 = new JButton("连接");
+
+    public JButton jb2 = new JButton("断开");
+
+    public void launch(){
+//设置服务端连接窗口的标题、位置、大小
+        this.setTitle("远程控制客户端---连接窗口");
+
+        this.setLocation(350, 200);
+
+        this.setSize(350, 100);
+//设置窗口始终置顶
+        this.setAlwaysOnTop(true);
+
+//设置一个层级面板
+        JLayeredPane jlp  =new JLayeredPane();
+
+        jlp.setLayout(new FlowLayout());
+
+
+        jlp.add(new JLabel("远程IP地址:"));
+
+        iptf.setText("");
+
+        porttf.setText("");
+
+        jlp.add(iptf);
+
+        jlp.add(new JLabel("端口:"));
+
+        jlp.add(porttf);
+//监听按钮点击事件
+        jb1.addMouseListener(new MouseAdapter(){
+
+            public void mouseClicked(MouseEvent e) {
+                try {
+                    Controller.connect(iptf.getText(),Integer.parseInt(porttf.getText().trim()));
+                } catch (NumberFormatException e1) {
+
+                    //端口号格式输入出错
+                    JOptionPane.showMessageDialog(null,"IP地址或端口号输入出错,无法取得连接。。","提示",JOptionPane.ERROR_MESSAGE);
+                    System.exit(0);
+                    destroy();
+
+                } catch (MyException e1) {
+                    JOptionPane.showMessageDialog(null,e1.info,"提示",JOptionPane.ERROR_MESSAGE);
+
+                }catch(Exception ed){
+
+                    // "远程不允许被控,无法取得连接。。
+                    JOptionPane.showMessageDialog(null,"远程不允许被控,无法取得连接。。","提示",JOptionPane.ERROR_MESSAGE);
+                    System.exit(0);
+                    destroy();
+
+                }
+                //连接成功
+            }
+        });
+
+        jb2.addMouseListener(new MouseAdapter(){
+
+            public void mouseClicked(MouseEvent e) {
+
+                JOptionPane.showMessageDialog(null, "断开控制端窗口","提示",JOptionPane.INFORMATION_MESSAGE);
+
+                System.exit(0);
+
+                destroy();
+
+            }
+
+        });
+
+        jlp.add(jb1);
+
+        jlp.add(jb2);
+
+        this.setLayeredPane(jlp);
+
+        this.addWindowListener(new WindowAdapter(){
+
+
+            public void windowClosing(WindowEvent e) {
+
+                // 关闭窗口
+
+                JOptionPane.showMessageDialog(null, "关闭连接窗口","提示",JOptionPane.INFORMATION_MESSAGE);
+
+                System.exit(0);
+            }
+
+        });
+
+        this.setVisible(true);
+
+    }
+//启动方法
+    public static void main(String[] args) {
+
+        // TODO Auto-generated method stub
+
+        new Server().launch();
+    }
+
+
+
+    public void destroy(){
+
+        this.destroy();
+
+    }
+
+}

+ 89 - 0
src/com/sziit/G06/thread/CaptureThread.java

@@ -0,0 +1,89 @@
+package com.sziit.G06.thread;
+
+import com.sun.image.codec.jpeg.JPEGCodec;
+import com.sun.image.codec.jpeg.JPEGImageEncoder;
+
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+
+/*
+ * 控制端实现画面回放(即是回放被控端隔一段时间从桌面捕获的画面图片)
+ * */
+public class CaptureThread extends Thread{
+
+    private DataOutputStream dataoutputstream;
+    private Toolkit tk ;
+    private Dimension dm ;
+    private Rectangle rec;
+    private Robot robot ;
+
+
+
+    public CaptureThread(DataOutputStream dataoutputstream) throws AWTException {
+        //1.获取dataoutputstream
+        this.dataoutputstream = dataoutputstream;
+
+        // 2.根据屏幕设定图片的大小
+        tk = Toolkit.getDefaultToolkit();
+        dm = tk.getScreenSize();
+        //抓取的长方形屏幕
+        rec = new Rectangle(0, 0, (int)dm.getWidth(), (int)dm.getHeight());
+
+        //3.建立robot对象
+        robot =new java.awt.Robot();
+    }
+
+   //// a.在被控制端,每隔一段一定的时间,将从桌面捕获的画面图片.
+    @Override
+    public void run() {
+        while (true) {
+//1.调用captureScreen抓取一次屏幕到缓冲区
+            byte[] data = new byte[0];
+            try {
+                data = captureScreen();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+//2.把缓冲器数据写到控制端
+                try {
+                    dataoutputstream.writeInt(data.length);
+                    dataoutputstream.write(data);
+                    dataoutputstream.flush();
+                    try {
+                        Thread.sleep(50);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    System.out.println("网络有问题,截屏失败");
+                }
+            }
+        }
+
+        ////b.用javax.io.ImagIO转成一个字节数组,从而将每一个画面的数据量大小,用数据输出流往控制端发送。
+    /*
+     * 获取一个截屏,放回到一个字节数组
+     */
+    private byte[] captureScreen() throws IOException {
+
+//获得一个屏幕的截图
+        BufferedImage bimage = robot.createScreenCapture(rec);
+//创建一段内存流
+        ByteArrayOutputStream byout = new ByteArrayOutputStream();
+
+        try {
+//将图片数据写入内存流中
+            ImageIO.write(bimage, "jpg", byout);
+        } catch (IOException e) {
+            System.out.println("截屏图片写入内存流中出现异常");
+            e.printStackTrace();
+        }
+        return byout.toByteArray();
+
+    }
+}

+ 106 - 0
src/com/sziit/G06/thread/EventReadThread.java

@@ -0,0 +1,106 @@
+package com.sziit.G06.thread;
+
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseWheelEvent;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/*
+ * 被控制端的事件回放(即回放控制端对被控制端的操作,包括:a.键盘事件(输入、删除)。
+ *                                              b.鼠标事件(点击、移动、滑轮滚动)。
+ * */
+public class EventReadThread extends Thread {
+
+    private ObjectInputStream ois;
+
+    public EventReadThread(ObjectInputStream ois) {
+//获得用于读取控制端事件对象的对象输入流,
+        this.ois = ois;
+    }
+
+    @Override
+   public void run() {
+////循环读控制端事件并回放
+       while (true) {
+          try {
+////读事件,回放事件
+                Object eventobj = ois.readObject();
+                InputEvent e = (InputEvent) eventobj;
+                actionEvent(e);
+            } catch (IOException | ClassNotFoundException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+//
+//    //回放事件的方法
+    private void actionEvent(InputEvent e) {
+        Robot robot = null;
+        try {
+            robot = new Robot();
+        } catch (AWTException e1) {
+            e1.printStackTrace();
+        }
+//如果是键盘事件,回放处理键盘操作
+        if (e instanceof KeyEvent) {
+            KeyEvent ke = (KeyEvent) e;
+            assert robot != null;
+            if (e.getID() == KeyEvent.KEY_PRESSED) {
+                robot.keyPress(ke.getKeyCode());
+            }
+            if (e.getID() == KeyEvent.KEY_RELEASED) {
+
+                robot.keyRelease(ke.getKeyCode());
+            }
+        }
+//如果是鼠标事件,回放处理鼠标操作
+        if (e instanceof MouseEvent) {
+            MouseEvent me = (MouseEvent) e;
+            int type = me.getID();
+            assert robot != null;
+            if (type == MouseEvent.MOUSE_PRESSED) { //按下
+
+                robot.mousePress(getMouseClick(me.getButton()));
+            }
+            if (type == MouseEvent.MOUSE_RELEASED) { //放开
+
+                robot.mouseRelease(getMouseClick(me.getButton()));
+            }
+            if (type == MouseEvent.MOUSE_MOVED) { //移动
+
+                robot.mouseMove(me.getX(), me.getY());
+            }
+            if (type == MouseEvent.MOUSE_DRAGGED) { //拖动
+
+                robot.mouseMove(me.getX(), me.getY());
+            }
+            if (type == MouseEvent.MOUSE_WHEEL) { //滑轮滚动
+
+                robot.mouseWheel(getMouseClick(me.getButton()));
+            }
+        }
+    }
+
+
+        /**
+         * 根据发送的Mouse事件对象,转变为通用的Mouse按键代码
+         *
+         * @param button
+         * @return
+         */
+    private int getMouseClick(int button) {
+        if (button == MouseEvent.BUTTON1) {
+            return InputEvent.BUTTON1_MASK;
+        }
+        if (button == MouseEvent.BUTTON2) {
+            return InputEvent.BUTTON2_MASK;
+        }
+        if (button == MouseEvent.BUTTON3) {
+            return InputEvent.BUTTON3_MASK;
+        }
+        return -1;
+    }
+}

+ 6 - 0
web/WEB-INF/web.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
+         version="4.0">
+</web-app>

+ 16 - 0
web/index.jsp

@@ -0,0 +1,16 @@
+<%--
+  Created by IntelliJ IDEA.
+  User: ASUS
+  Date: 2020/12/21
+  Time: 9:59
+  To change this template use File | Settings | File Templates.
+--%>
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<html>
+  <head>
+    <title>$Title$</title>
+  </head>
+  <body>
+  $END$
+  </body>
+</html>