溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

java實現(xiàn)遠程桌面的實例代碼

發(fā)布時間:2020-10-18 03:22:17 來源:腳本之家 閱讀:189 作者:一艷傾華 欄目:編程語言

java實現(xiàn)遠程桌面的實例代碼

控制端將鼠標(biāo)事件傳遞到服務(wù)端

服務(wù)端拿到鼠標(biāo)事件之后傳輸?shù)娇蛻舳?/strong>

客戶端拿到鼠標(biāo)事件之后,通過robot類即可完成,并且截屏將圖片發(fā)給服務(wù)器,服務(wù)器再發(fā)給控制端

java實現(xiàn)遠程桌面的實例代碼

被我簡化之后得到

java實現(xiàn)遠程桌面的實例代碼

//先介紹一下robot類的簡單使用
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;
/**
 * 使用robot
 * @author 啞元
 *
 */
public class RobotTest {
 public static void main(String[] args) throws AWTException {
  Robot r = new Robot();
  r.mouseMove(300, 500);//鼠標(biāo)移動
  r.mousePress(InputEvent.BUTTON1_MASK ); //鼠標(biāo)按下
  r.mouseRelease(InputEvent.BUTTON1_MASK);//鼠標(biāo)松開
  r.keyPress((int)'A'); //鍵盤按下 (int)'A'表示將A轉(zhuǎn)換成鍵盤對應(yīng)的key
  r.keyRelease((int)'A'); //鍵盤松開
 }
}

//屏幕抓取
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;
/**
 * 抓取本地桌面圖片
 * @author 啞元
 *
 */
public class ScreenTest {
 public static void main(String[] args) throws AWTException, InterruptedException {
  Robot robot = new Robot(); 
  JFrame jframe = new JFrame();
  jframe.setSize(1200, 700);
  JLabel label = new JLabel();
  jframe.add(label);
  //四個參數(shù)x y width height
  jframe.setVisible(true);
  jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE );
  //構(gòu)建一個死循環(huán)動態(tài)截取
  while(true){
   BufferedImage image = robot.createScreenCapture(new Rectangle(0,0,1366,768));//截取屏幕
   label.setIcon(new ImageIcon(image));
   Thread.sleep(50);
  } 
 }
}

//遠程控制原理講解
//分為server端和client端,
//原本server端只作為轉(zhuǎn)發(fā),作為演示,就不寫轉(zhuǎn)發(fā)
//也就是client端控制server端E
/**
* 這里我采用的是,在client端也就是操控端,接收到server端發(fā)送過來的screen之后,然后發(fā)送鼠標(biāo)事件過去
* 然后再用robot處理
* 傳輸方式用socket+io即可處理
* 屏幕截取和圖片壓縮采用了robot的屏幕截取功能和jdk自帶的圖片編碼器,將其轉(zhuǎn)換成一個字節(jié)數(shù)組
* 發(fā)送給server端之后,robot通過io+socket可以直接拿到object對象,強制轉(zhuǎn)換成InputEvent(keyEvent和MouseEvent都繼承)之后
* 通過判斷event類型,分別處理即可,這里在服務(wù)端需要用到兩個線程,一個是屏幕截取和發(fā)送給客戶端,一個是用來監(jiān)聽客戶端
* 傳遞過來的事件
*/

//下面是具體實現(xiàn)代碼

//server主程
import java.awt.AWTException;
import java.awt.Event;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * 服務(wù)端
 * @author 啞元
 *
 */
public class Server {
 public static void main(String[] args) throws IOException {
  ServerSocket server = new ServerSocket(80);
  System.out.println("服務(wù)器已經(jīng)正常啟動");
  Socket socket = server.accept();//等待接收請求,阻塞方法
  System.out.println("有客戶端連接");
  DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
  //將客戶端與服務(wù)器端鏈接的輸出流交個ImageThread處理
  ImageThread imageThread = new ImageThread(dos);
  new Thread(imageThread).start();
  new Thread(new EventThread(new ObjectInputStream(socket.getInputStream()))).start();
 }
}
/**
 * 用來處理接收過來的鼠標(biāo)事件或者鍵盤事件
 */
class EventThread implements Runnable{
 private ObjectInputStream ois;
 private Robot robot;
 public EventThread(ObjectInputStream ois) {
  this.ois = ois;
 }
 @Override
 public void run() {
  try {
   robot = new Robot();
   while(true){
    InputEvent event = (InputEvent)ois.readObject();//得知由客戶端傳遞過來的是一個object對象
    actionEvent(event);//處理事件
   }
  } catch (AWTException e) {
   e.printStackTrace();
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }finally{
   try {
    ois.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
 /**
  * 事件處理,用來判斷事件類型,并用robot類執(zhí)行
  * @param event
  */
 public void actionEvent(InputEvent event){
  System.out.println(event);
  if(event instanceof KeyEvent){
   KeyEvent e = (KeyEvent)event;
   int type = e.getID();//拿到事件類型
   if(type==Event.KEY_PRESS){
    robot.keyPress(e.getKeyCode());
   }else if(type == Event.KEY_RELEASE){
    robot.keyRelease(e.getKeyCode());
   }
  }else if(event instanceof MouseEvent){
   MouseEvent e = (MouseEvent)event;
   int type = e.getID();
   if(type == Event.MOUSE_MOVE){
    robot.mouseMove(e.getX(),e.getY());
   }else if(type == Event.MOUSE_DOWN){
    robot.mousePress(getMouseKey(type));
   }else if(type == Event.MOUSE_UP){
    robot.mouseRelease(getMouseKey(type));
   }else if(type == Event.MOUSE_DRAG){
    robot.mouseMove(e.getX(), e.getY());//鼠標(biāo)拖動
   }
  }
 }
 /**
  * 返回鼠標(biāo)的真正事件,鼠標(biāo)時間不能直接處理,需要進過轉(zhuǎn)換
  * @return
  */
 public int getMouseKey(int button){
  if(button == MouseEvent.BUTTON1){//鼠標(biāo)左鍵
   return InputEvent.BUTTON1_MASK;
  }else if(button == MouseEvent.BUTTON2){//鼠標(biāo)右鍵
   return InputEvent.BUTTON2_MASK;
  }else if(button == MouseEvent.BUTTON3){//滾輪
   return InputEvent.BUTTON3_MASK;
  }else{
   return 0;
  }
 }
}

//屏幕截取器和發(fā)送器,這里需要拿到socket的out流
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import com.sun.image.codec.jpeg.*;
/**
 * 用來將圖片數(shù)據(jù)發(fā)送
 * @author 啞元
 *
 */
public class ImageThread implements Runnable{
 DataOutputStream dos = null; //數(shù)據(jù)輸出流
 public ImageThread(DataOutputStream dos){
  this.dos = dos;
 }
 @Override
 public void run() {
  try {
   Robot robot = new Robot();
   //截取整個屏幕
   Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
   /*
   int width = (int)dimension.getWidth();
   int height = (int)dimension.getWidth();
   Rectangle rec = new Rectangle(0,0,width,height);
   */
   Rectangle rec = new Rectangle(dimension);
   BufferedImage image;
   byte imageBytes[];
   while(true){
    image = robot.createScreenCapture(rec);
    imageBytes = getImageBytes(image);
    dos.writeInt(imageBytes.length);
    dos.write(imageBytes);
    dos.flush();
    Thread.sleep(50); //線程睡眠
   }
  } catch (AWTException e) {
   e.printStackTrace();
  } catch (ImageFormatException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }finally{
   try {
    if(dos!= null) dos.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
 /**
  * 壓縮圖片
  * @param 需要壓縮的圖片
  * @return 壓縮后的byte數(shù)組
  * @throws IOException 
  * @throws ImageFormatException 
  */
 public byte[] getImageBytes(BufferedImage image) throws ImageFormatException, IOException{
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  //壓縮器壓縮,先拿到存放到byte輸出流中
  JPEGImageEncoder jpegd = JPEGCodec.createJPEGEncoder(baos);
  //將iamge壓縮
  jpegd.encode(image);
  //轉(zhuǎn)換成byte數(shù)組
  return baos.toByteArray(); 
 }
}

--------------------------------------------------------------------------------------
//client端,用來接收creen圖片和發(fā)送鼠標(biāo)事件
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;
/**
 * 客戶端
 * @author 啞元
 *
 */
public class Client {
 public static void main(String args[]) throws UnknownHostException, IOException{
  Socket s = new Socket("127.0.0.1",80);
  DataInputStream dis = new DataInputStream(s.getInputStream());
  ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
  ClientWindow cw = new ClientWindow(oos);
  byte[] imageBytes;
  while(true){
   imageBytes = new byte[dis.readInt()]; //先拿到傳過來的數(shù)組長度
   dis.readFully(imageBytes); //所有的數(shù)據(jù)存放到byte中
   cw.repainImage(imageBytes);
  }
 }
}
/**
 * 客戶端窗體
 * @author 啞元
 *
 */
class ClientWindow extends JFrame{
 private ObjectOutputStream oos;
 private JLabel label;
 //重寫背景圖片方法
 public void repainImage(byte [] imageBytes){
  label.setIcon(new ImageIcon(imageBytes));
  this.repaint();
 }
 public ClientWindow(ObjectOutputStream oos){
  this.oos = oos;
  this.setTitle("遠程控制程序");
  label = new JLabel();
  JPanel p = new JPanel();
  p.add(label);
  JScrollPane scroll = new JScrollPane(p);//給p面板添加滾動條
  this.add(scroll);
  this.setSize(1024,768);
  this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
  this.setVisible(true);
  this.addKeyListener(new KeyListener() {
   @Override
   public void keyTyped(KeyEvent e) {
    // TODO Auto-generated method stub
   }
   @Override
   public void keyReleased(KeyEvent e) {
    sendEvent(e);
   }
   @Override
   public void keyPressed(KeyEvent e) {
    sendEvent(e);
   }
  });
  label.addMouseListener(new MouseListener() {
   @Override
   public void mouseReleased(MouseEvent e) {
    sendEvent(e);
   }
   @Override
   public void mousePressed(MouseEvent e) {
    sendEvent(e);
   }
   @Override
   public void mouseClicked(MouseEvent e) {
    sendEvent(e);
   }
   @Override
   public void mouseEntered(MouseEvent e) {
    // TODO Auto-generated method stub
   }
   @Override
   public void mouseExited(MouseEvent e) {
    // TODO Auto-generated method stub
   }
  });
 }
 public void sendEvent(InputEvent event){
  try {
   oos.writeObject(event);
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

以上這篇java實現(xiàn)遠程桌面的實例代碼就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持億速云。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI