当前位置: 移动技术网 > IT编程>开发语言>Java > java实现远程桌面的实例代码

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

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实现远程桌面的实例代码就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网