最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)遠(yuǎn)程控制技術(shù)完整源代碼分享

 更新時(shí)間:2016年08月23日 14:47:11   作者:Charchunchiu  
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)遠(yuǎn)程控制技術(shù)完整源代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

Java實(shí)現(xiàn)遠(yuǎn)程控制技術(shù)

java自帶的java.net.和java.awt.robot. 的混合可以用于實(shí)現(xiàn)通過網(wǎng)絡(luò)對(duì)另一臺(tái)計(jì)算機(jī)的遠(yuǎn)程控制,其中包括控制遠(yuǎn)程計(jì)算機(jī)鼠標(biāo)的動(dòng)作和鍵盤的輸入,以及實(shí)時(shí)獲得遠(yuǎn)程計(jì)算機(jī)屏幕的圖像。本文將用簡潔的語言和由淺入深的邏輯,教大家如何掌握這個(gè)技術(shù)。
首先先看一下效果圖:
遠(yuǎn)程端計(jì)算機(jī)界面:

 

控制端計(jì)算機(jī)界面:

 

控制端輸入:

 

遠(yuǎn)程端輸入:

一下開始詳細(xì)介紹遠(yuǎn)程控制的技術(shù)思路。
首先兩臺(tái)計(jì)算機(jī)通過java.net的Socket來進(jìn)行連接。

一端先打開一個(gè)ServerSocket,然后另外一端用socket進(jìn)行連接。

服務(wù)器端

應(yīng)該設(shè)置一個(gè)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());
 }

客戶機(jī)端
應(yīng)該用socket去連接服務(wù)器,并且初始化輸入輸出流:

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


 }

這樣兩臺(tái)計(jì)算機(jī)就鏈接在一起并且可以通過流(InputStream和OutputStream)來交換數(shù)據(jù)了

接下來大家可以想一想,要實(shí)現(xiàn)遠(yuǎn)程控制的兩臺(tái)計(jì)算機(jī)需要交換什么信息呢?首先被控制端需要不斷向控制端提供截取的屏幕圖像(這個(gè)我們將會(huì)用java.awt.robot來實(shí)現(xiàn)),然后鼠標(biāo)和鍵盤根據(jù)控制端傳來的事件(inputEvent)來做出相同的操作(用robot來實(shí)現(xiàn))。然后控制端當(dāng)然首先要接收被控制端傳來的圖像并且反映到一個(gè)面板上(pane),然后監(jiān)聽本機(jī)上鍵盤鼠標(biāo)的動(dòng)作再傳給被控制端的主機(jī)(我們通過在面板pane上設(shè)置一個(gè)監(jiān)聽器listener來實(shí)現(xiàn))

這里遇到的一個(gè)問題就是用于傳送的圖片無論是用image還是用bufferedImage都是不可串行化的。所以不能用I/OStream進(jìn)行傳送,所以為了解決這個(gè)問題,我們需要把圖像數(shù)據(jù)封裝在一個(gè)類里面并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;  // 文件內(nèi)容

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


}

這樣就可以實(shí)現(xiàn)圖像通過ObjectInputStream和ObjectOutputStream的串行化傳播了

了解了以上基礎(chǔ)之后首先我們要完成控制端的UI界面設(shè)置,圖片接收,和鍵盤鼠標(biāo)動(dòng)作監(jiān)聽:

首先是設(shè)置接收?qǐng)D片:

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

這樣接收了來自O(shè)bjectInputStream的Message類之后就可以把圖片重新設(shè)置到面板pane的大小然后展示出來

下一步就是設(shè)置面板屬性和監(jiān)聽器:

public static void showUI(){
 //控制臺(tái)標(biāo)題
  JFrame jf = new JFrame("控制臺(tái)");setListener(jf);
  //控制臺(tái)大小
  jf.setSize(500, 400);
  //imag_lab用于存放畫面
  imag_lab = new JLabel();
  jf.add(imag_lab);
  //設(shè)置控制臺(tái)可見
  jf.setVisible(true);
  //控制臺(tái)置頂
  jf.setAlwaysOnTop(true);
  jf.setResizable(true);
  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


 }

監(jiān)聽器:

 public static void setListener( JFrame frame){
  //panel設(shè)置監(jiān)聽器
  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();
  }

 以上就完成了控制端。

接下來我們將構(gòu)建被控制端:
被控制端需要使用robot來截圖并發(fā)送,而且需要寫一個(gè)方法來對(duì)接收到的InputEvent進(jìn)行反應(yīng)
首先是截圖和發(fā)送:

 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++) {
  //截取指定大小的屏幕區(qū)域
  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\目錄作為臨時(shí)文件的存放地方,讀者使用這個(gè)代碼的時(shí)候需要自己設(shè)置臨時(shí)文檔的存放

然后實(shí)現(xiàn)robot對(duì)于接收到的InputEvent指令進(jìn)行操作:

 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 ; //鼠標(biāo)事件
 MouseWheelEvent mwevent = null ;//鼠標(biāo)滾動(dòng)事件
 KeyEvent kevent = null ; //鍵盤事件
 int mousebuttonmask = -100; //鼠標(biāo)按鍵

 switch (event.getID()){
 case MouseEvent.MOUSE_MOVED :   //鼠標(biāo)移動(dòng)
  mevent = ( MouseEvent )event ;
  action.mouseMove( mevent.getX() , mevent.getY() );
  break ;
 case MouseEvent.MOUSE_PRESSED :   //鼠標(biāo)鍵按下
  mevent = ( MouseEvent ) event;
  action.mouseMove( mevent.getX() , mevent.getY() );
  mousebuttonmask = getMouseClick(mevent.getButton() );
  if(mousebuttonmask != -100)
  action.mousePress(mousebuttonmask);
  break;
  case MouseEvent.MOUSE_RELEASED :  //鼠標(biāo)鍵松開
  mevent = ( MouseEvent ) event;
  action.mouseMove( mevent.getX() , mevent.getY() );
  mousebuttonmask = getMouseClick( mevent.getButton() );//取得鼠標(biāo)按鍵
  if(mousebuttonmask != -100)
  action.mouseRelease( mousebuttonmask );
  break ;
 case MouseEvent.MOUSE_WHEEL :   //鼠標(biāo)滾動(dòng)
  mwevent = ( MouseWheelEvent ) event ;
  action.mouseWheel(mwevent.getWheelRotation());
  break ;
  case MouseEvent.MOUSE_DRAGGED :   //鼠標(biāo)拖拽
  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) { //取得鼠標(biāo)按鍵
 if (button == MouseEvent.BUTTON1) //左鍵 ,中間鍵為BUTTON2
  return InputEvent.BUTTON1_MASK;
 if (button == MouseEvent.BUTTON3) //右鍵
  return InputEvent.BUTTON3_MASK;
 return -100;
 } 

 整個(gè)程序到這里就可以結(jié)束了。上面的程序并沒有實(shí)現(xiàn)對(duì)機(jī)器人類線程的封裝。完整可以用的代碼可以在以下站內(nèi)資源處下載我的資源:http://xiazai.jb51.net/201608/yuanma/Java-RomoteControl(jb51.net).rar

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringMVC靜態(tài)資源配置過程詳解

    SpringMVC靜態(tài)資源配置過程詳解

    在javaweb項(xiàng)目中配置了DispatcherServlet的情況下,如果不進(jìn)行額外配置的話,幾乎所有的請(qǐng)求都會(huì)走這個(gè)servlet來處理,默認(rèn)靜態(tài)資源按路徑是訪問不到的會(huì)報(bào)404錯(cuò)誤,下面就來講一講如何配置才能訪問到靜態(tài)資源吧
    2022-08-08
  • SpringData如何通過@Query注解支持JPA語句和原生SQL語句

    SpringData如何通過@Query注解支持JPA語句和原生SQL語句

    這篇文章主要介紹了SpringData如何通過@Query注解支持JPA語句和原生SQL語句,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 100-200之間所有素?cái)?shù)求和程序代碼(二個(gè)版本)

    100-200之間所有素?cái)?shù)求和程序代碼(二個(gè)版本)

    寫一個(gè)求100-200之間素?cái)?shù),并求和的程序,大家參考使用吧
    2013-11-11
  • Spring Aop如何給Advice傳遞參數(shù)

    Spring Aop如何給Advice傳遞參數(shù)

    這篇文章主要介紹了Spring Aop如何給Advice傳遞參數(shù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • SpringBoot中使用@Value注解注入詳解

    SpringBoot中使用@Value注解注入詳解

    這篇文章主要介紹了SpringBoot中的@Value注入詳解,在SpringBoot中,@Value注解可以注入一些字段的普通屬性,并且會(huì)自動(dòng)進(jìn)行類型轉(zhuǎn)換,本文對(duì)這些類型進(jìn)行總結(jié),需要的朋友可以參考下
    2023-08-08
  • Java線程死鎖代碼詳解

    Java線程死鎖代碼詳解

    本篇文章主要介紹了Java線程死鎖代碼詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2021-11-11
  • 淺談Java中向上造型向下造型和接口回調(diào)中的問題

    淺談Java中向上造型向下造型和接口回調(diào)中的問題

    這篇文章主要介紹了淺談Java中向上造型向下造型和接口回調(diào)中的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • java 創(chuàng)建線程的四種方式

    java 創(chuàng)建線程的四種方式

    這篇文章主要介紹了java 創(chuàng)建線程的四種方式,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-11-11
  • 基于java 線程的幾種狀態(tài)(詳解)

    基于java 線程的幾種狀態(tài)(詳解)

    下面小編就為大家?guī)硪黄趈ava 線程的幾種狀態(tài)(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就想給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • java 橋模式(Bridge Pattern)詳解

    java 橋模式(Bridge Pattern)詳解

    這篇文章主要介紹了java 橋模式(Bridge Pattern)詳解的相關(guān)資料,需要的朋友可以參考下
    2016-10-10

最新評(píng)論

固原市| 昂仁县| 镇安县| 罗平县| 林周县| 大名县| 山东| 神池县| 中山市| 浠水县| 南溪县| 亳州市| 彭泽县| 平度市| 铁力市| 子长县| 广德县| 台湾省| 宜昌市| 石河子市| 昌平区| 巴东县| 和田市| 尚志市| 布拖县| 喀喇| 简阳市| 赞皇县| 浙江省| 惠东县| 京山县| 连江县| 新巴尔虎右旗| 鄂伦春自治旗| 泸州市| 福泉市| 遂川县| 旌德县| 云浮市| 沐川县| 全南县|