Java实现远程控制技术(附完整源代码)

Java实现远程控制技术

java自带的java.net.和java.awt.robot. 的混合可以用于实现通过网络对另一台计算机的远程控制,其中包括控制远程计算机鼠标的动作和键盘的输入,以及实时获得远程计算机屏幕的图像。本文将用简洁的语言和由浅入深的逻辑,教大家如何掌握这个技术。
首先先看一下效果图:
远程端计算机界面:
这里写图片描述
控制端计算机界面:
这里写图片描述
控制端输入:
这里写图片描述
远程端输入:
这里写图片描述
一下开始详细介绍远程控制的技术思路。
首先两台计算机通过java.net的Socket来进行连接。
一端先打开一个ServerSocket,然后另外一端用socket进行连接
服务器端
应该设置一个ServerSocket,并且初始化需要用到的输入输出流:

    public static void OpenServer() throws IOException, ClassNotFoundException{
        System.out.println("ServerStart.....");
        ServerSocket server = new ServerSocket(7777);
        socket = server.accept();
        System.out.println("连接上...\n"+socket);
        OIS = new ObjectInputStream(socket.getInputStream());
        OOS=new ObjectOutputStream(socket.getOutputStream());
        }

客户机端
应该用socket去连接服务器,并且初始化输入输出流:

public static void StartConnection(String IP,int port) throws UnknownHostException, IOException, AWTException{
        socket = new Socket("192.168.0.106",7777);
        if(socket.isConnected()){
            System.out.println("socket connected..."+socket);
        }
        OOS = new ObjectOutputStream(socket.getOutputStream());
        OIS = new ObjectInputStream(socket.getInputStream());


    }

这样两台计算机就链接在一起并且可以通过流(InputStream和OutputStream)来交换数据了

接下来大家可以想一想,要实现远程控制的两台计算机需要交换什么信息呢?首先被控制端需要不断向控制端提供截取的屏幕图像(这个我们将会用java.awt.robot来实现),然后鼠标和键盘根据控制端传来的事件(inputEvent)来做出相同的操作(用robot来实现)。然后控制端当然首先要接收被控制端传来的图像并且反映到一个面板上(pane),然后监听本机上键盘鼠标的动作再传给被控制端的主机(我们通过在面板pane上设置一个监听器listener来实现)

这里遇到的一个问题就是用于传送的图片无论是用image还是用bufferedImage都是不可串行化的。所以不能用I/OStream进行传送,所以为了解决这个问题,我们需要把图像数据封装在一个类里面并implements Serializable接口
图像类如下:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;

public class Message implements Serializable {
     private static final long serialVersionUID = 1L;
        private String fileName;            // 文件名称

        private long fileLength;             // 文件长度
        private byte[] fileContent;          // 文件内容

        public Message(){

        }
        public Message(String filePath) throws IOException{
            File file = new File(filePath);
            this.fileLength=file.length();
            this.fileName=file.getName();

            FileInputStream FIS = new FileInputStream(filePath);
            byte[] bytes = new byte[(int)fileLength];
            FIS.read(bytes,0,(int)fileLength);
            this.fileContent=bytes;

        }



        public String getFileName()
        { return fileName;}

        public void setFileName(String fileName)

        { this.fileName = fileName;}
        public long getFileLength()
       { return fileLength;
       }

       public void setFileLength(long fileLength)
       {this.fileLength = fileLength;}



        public byte[] getFileContent()
        {return fileContent;}
        public void setFileContent(byte[] fileContent)
        {this.fileContent = fileContent;}


}

这样就可以实现图像通过ObjectInputStream和ObjectOutputStream的串行化传播了

了解了以上基础之后首先我们要完成控制端的UI界面设置,图片接收,和键盘鼠标动作监听:

首先是设置接收图片:

public static void reveivePic() throws ClassNotFoundException, IOException{
        Message g = (Message)OIS.readObject();
        FileOutputStream FOS = new FileOutputStream("D:\\OUT\\"+g.getFileName());
        FOS.write(g.getFileContent(),0,(int)g.getFileLength());
        FOS.flush();

        FileInputStream FIS= new FileInputStream("D:\\OUT\\"+g.getFileName());
        BufferedImage BI = ImageIO.read(FIS);
        IIC=new ImageIcon(BI);

        Image img = IIC.getImage();
        Toolkit tk = Toolkit.getDefaultToolkit() ;
            Dimension d =tk.getScreenSize();

            int w = d.width;
            int h =d.height;
               BufferedImage bi = resize(img,800,600);


               imag_lab.setIcon(new ImageIcon(bi));
               imag_lab.repaint();//销掉以前画的背景
        }

 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();
         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;
  }

这样接收了来自ObjectInputStream的Message类之后就可以把图片重新设置到面板pane的大小然后展示出来

下一步就是设置面板属性和监听器:

public static void showUI(){
        //控制台标题
           JFrame jf = new JFrame("控制台");setListener(jf);
           //控制台大小
           jf.setSize(500, 400);
           //imag_lab用于存放画面
           imag_lab = new JLabel();
           jf.add(imag_lab);
           //设置控制台可见
           jf.setVisible(true);
           //控制台置顶
           jf.setAlwaysOnTop(true);
           jf.setResizable(true);
           jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    }

监听器:

      public static void setListener( JFrame frame){
           //panel设置监听器
             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) {

                   }
     });
             frame.addMouseWheelListener(new MouseWheelListener(){
                   public void mouseWheelMoved(MouseWheelEvent e) {
                         sendEventObject(e);       
                   }
            });
             frame.addMouseMotionListener(new MouseMotionListener(){

                   public void mouseDragged(MouseEvent e) {

                          sendEventObject(e);
                   }

                   public void mouseMoved(MouseEvent e) {


                          sendEventObject(e);

                   }
            });
             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 static void sendEventObject(InputEvent event){
             try{  System.out.println("send");
               OOS.writeObject(event);
               OOS.flush();

             }catch(Exception ef){
                      ef.printStackTrace();
               }

以上就完成了控制端。

接下来我们将构建被控制端:
被控制端需要使用robot来截图并发送,而且需要写一个方法来对接收到的InputEvent进行反应
首先是截图和发送:

    public static void CapturePic() throws AWTException, IOException{
        robot= new Robot();
        Message msg = null;
        Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
        java.awt.Dimension dm =tk.getScreenSize();
        java.awt.Robot robot = new java.awt.Robot();
           for (int i = 0; i < 50; i++) {
               //截取指定大小的屏幕区域
               Rectangle rec = new Rectangle(0, 0, (int) dm.getWidth(), (int) dm
                      .getHeight());
               BufferedImage bimage = robot.createScreenCapture(rec);
               //将图片保存到文件中
               String filePath = "D:\\OUT\\screenshot"+i+".jpeg";
               FileOutputStream fops =new FileOutputStream(filePath);
               javax.imageio.ImageIO.write(bimage, "jpeg", fops);
               fops.flush();
               fops.close();
               msg =new Message(filePath);

               System.out.println(msg.getFileName());
               System.out.println("send");
                OOS.writeObject(msg);
                OOS.flush();

           }
     }

注意到这段代码中使用了D:\OUT\目录作为临时文件的存放地方,读者使用这个代码的时候需要自己设置临时文档的存放

然后实现robot对于接收到的InputEvent指令进行操作:

    public  void action() throws AWTException, ClassNotFoundException, IOException{
        Robot robot= new Robot();
        while(true){

        InputEvent e =(InputEvent)OIS.readObject();
                if(e!=null){
        handleEvents(robot,e);}
        }

    }

    public static void handleEvents(Robot action,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 static int getMouseClick(int button) {    //取得鼠标按键
        if (button == MouseEvent.BUTTON1) //左键 ,中间键为BUTTON2
            return InputEvent.BUTTON1_MASK;
        if (button == MouseEvent.BUTTON3) //右键
            return InputEvent.BUTTON3_MASK;
        return -100;
    }   

整个程序到这里就可以结束了。上面的程序并没有实现对机器人类线程的封装。完整可以用的代码可以在以下站内资源处下载我的资源:
http://download.csdn.net/detail/charchunchiu/9609473
谢谢大家
(完)

  • 12
    点赞
  • 120
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
实现电脑远程控制的方式有很多种,其中常见的方法是使用 Socket 编程实现远程控制。下面是一个简单的 Java 实现远程控制的示例代码: Server 端代码: ```java import java.io.*; import java.net.*; public class Server { public static void main(String[] args) { try { ServerSocket server = new ServerSocket(8888); System.out.println("等待客户端连接..."); Socket socket = server.accept(); System.out.println("客户端已连接:" + socket.getRemoteSocketAddress()); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println("收到客户端消息:" + inputLine); if (inputLine.equals("exit")) { break; } else { Runtime.getRuntime().exec(inputLine); out.println("命令已执行"); } } in.close(); out.close(); socket.close(); server.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` Client 端代码: ```java import java.io.*; import java.net.*; public class Client { public static void main(String[] args) { try { Socket socket = new Socket("localhost", 8888); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); if (userInput.equals("exit")) { break; } else { System.out.println("服务器回复:" + in.readLine()); } } in.close(); out.close(); stdIn.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` 以上代码实现了一个简单的远程控制功能,可以通过客户端向服务器发送命令实现远程控制。需要注意的是,这个示例代码只是为了演示远程控制的原理,实际使用中还需要进行安全性考虑,避免被非法操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值