java實現遠端桌面的執行個體代碼,java執行個體代碼
java實現遠端桌面的執行個體代碼
控制端將滑鼠事件傳遞到服務端
服務端拿到滑鼠事件之後傳輸到用戶端
用戶端拿到滑鼠事件之後,通過robot類即可完成,並且截屏將圖片發給伺服器,伺服器再發給控制端
被我簡化之後得到
//先介紹一下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);//滑鼠移動 r.mousePress(InputEvent.BUTTON1_MASK ); //滑鼠按下 r.mouseRelease(InputEvent.BUTTON1_MASK);//滑鼠鬆開 r.keyPress((int)'A'); //鍵盤按下 (int)'A'表示將A轉換成鍵盤對應的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); //四個參數x y width height jframe.setVisible(true); jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE ); //構建一個死迴圈動態截取 while(true){ BufferedImage image = robot.createScreenCapture(new Rectangle(0,0,1366,768));//截取螢幕 label.setIcon(new ImageIcon(image)); Thread.sleep(50); } }}
//遠端控制原理講解
//分為server端和client端,
//原本server端只作為轉寄,作為示範,就不寫轉寄
//也就是client端控制server端E
/**
* 這裡我採用的是,在client端也就是操控端,接收到server端發送過來的screen之後,然後發送滑鼠事件過去
* 然後再用robot處理
* 傳輸方式用socket+io即可處理
* 螢幕截取和圖片壓縮採用了robot的螢幕截取功能和jdk內建的圖片編碼器,將其轉換成一個位元組數組
* 發送給server端之後,robot通過io+socket可以直接拿到object對象,強制轉換成InputEvent(keyEvent和MouseEvent都繼承)之後
* 通過判斷event類型,分別處理即可,這裡在服務端需要用到兩個線程,一個是螢幕截取和發送給用戶端,一個是用來監聽用戶端
* 傳遞過來的事件
*/
//下面是具體實現代碼
//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;/** * 服務端 * @author 啞元 * */public class Server { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(80); System.out.println("伺服器已經正常啟動"); Socket socket = server.accept();//等待接收請求,阻塞方法 System.out.println("有用戶端串連"); DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); //將用戶端與伺服器端連結的輸出資料流交個ImageThread處理 ImageThread imageThread = new ImageThread(dos); new Thread(imageThread).start(); new Thread(new EventThread(new ObjectInputStream(socket.getInputStream()))).start(); }}/** * 用來處理接收過來的滑鼠事件或者鍵盤事件 */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類執行 * @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());//滑鼠拖動 } } } /** * 返回滑鼠的真正事件,滑鼠時間不能直接處理,需要進過轉換 * @return */ public int getMouseKey(int button){ if(button == MouseEvent.BUTTON1){//滑鼠左鍵 return InputEvent.BUTTON1_MASK; }else if(button == MouseEvent.BUTTON2){//滑鼠右鍵 return InputEvent.BUTTON2_MASK; }else if(button == MouseEvent.BUTTON3){//滾輪 return InputEvent.BUTTON3_MASK; }else{ return 0; } }}//螢幕截取器和發送器,這裡需要拿到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.*;/** * 用來將圖片資料發送 * @author 啞元 * */public class ImageThread implements Runnable{ DataOutputStream dos = null; //資料輸出資料流 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數組 * @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); //轉換成byte數組 return baos.toByteArray(); }}--------------------------------------------------------------------------------------//client端,用來接收creen圖片和發送滑鼠事件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()]; //先拿到傳過來的數組長度 dis.readFully(imageBytes); //所有的資料存放到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實現遠端桌面的執行個體代碼就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援幫客之家。