首页 > 开发 > Java > 正文

java实现远程桌面的实例代码

2020-07-28 14:51:48
字体:
来源:转载
供稿:网友

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();  } }}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表