java通过控制鼠标实现屏幕广播的方法
本文实例讲述了java通过控制鼠标实现屏幕广播的方法。分享给大家供大家参考。具体分析如下:
在前面一篇《java实现屏幕共享功能实例分析》中提到截取屏幕时是没鼠标,为了看到教师端界面上的鼠标,可以在截取屏幕的时候,把鼠标绘制到每一张截图上去,但是由于截图的时候是一张张截取的,所以看到的鼠标难免会有点卡,之前写了java鼠标操控小程序,可以通过这种方式来看到鼠标的演示。
实现的方式也挺简单的,前面两篇文章分别实现了鼠标控制和不带鼠标的屏幕分享功能,把这两个结合一下就ok了,下面简单分析下。
服务端,将SendScreenImg和SendMouseMessage看作两个工具类,分别监听不同的端口,他们两个都实现了Thread类,我们用线程池ExecutorService类控制他们。
使用了两个端口,因为暂时还不知道该如何吧鼠标信息和图片的信息一起发送,或许可以把图片转换成字节数组的形式,把鼠标的坐标放在数组前面,不过这样的话鼠标可能也会不连贯,因为传送鼠标坐标的速度会比传图片的要快一些,嗯,有空再试试。
客户端类比上面就是了。
下面是代码:
服务端:
主程序:
/* *屏幕广播类,调用了两个工具类:发送截屏信息的类和发送鼠标的信息类,利用了线程池。 */ publicclassBroderCast{ public staticvoidmain(String[]args) { newBroderCast(); System.out.println("开始"); } publicBroderCast() { ExecutorServiceexector=Executors.newFixedThreadPool(2); exector.execute(newSendScreenImg()); exector.execute(newSendMouseMessage()); } }
发送截图代码:
importjava.awt.Dimension; importjava.awt.Rectangle; importjava.awt.Robot; importjava.awt.Toolkit; importjava.awt.image.BufferedImage; importjava.io.DataOutputStream; importjava.io.IOException; importjava.net.ServerSocket; importjava.net.Socket; importjava.util.zip.ZipEntry; importjava.util.zip.ZipOutputStream; importjavax.imageio.ImageIO; /* *工具类:发送教师端截屏信息给学生端,没有鼠标信息,使用了8002号端口 * 可以在发送的图片上面组件绘制鼠标的信息,从而实现在学生端界面上见到鼠标信息,暂未实现该功能 * */ public classSendScreenImgextendsThread { publicintserverPort=8002; privateServerSocketserverSocket; privateRobotrobot; public Dimensionscreen; publicRectanglerect; privateSocketsocket; publicstaticvoidmain(Stringargs[]) { newSendScreenImg().start(); } publicvoidchangeServerPort(intserverPort) { if(this.serverPort==serverPort)return; try{ this.serverSocket.close(); //有必要先关闭当前端口 this.serverPort=serverPort; serverSocket=newServerSocket(this.serverPort); serverSocket.setSoTimeout(8000000); }catch(Exceptione){} } //构造方法 开启套接字连接 机器人robot 获取屏幕大小 publicSendScreenImg() { try{ serverSocket=newServerSocket(getServerPort()); serverSocket.setSoTimeout(864000000); robot=newRobot(); }catch(Exceptione){ e.printStackTrace(); } screen=Toolkit.getDefaultToolkit().getScreenSize(); //获取主屏幕的大小 rect=newRectangle(screen); //构造相应大小的矩形 } @Override publicvoidrun() { //实时等待接收截屏消息 while(true){ try{ socket=serverSocket.accept(); ZipOutputStreamzip=newZipOutputStream(newDataOutputStream(socket.getOutputStream())); zip.setLevel(9); //设置压缩级别 try{ BufferedImageimg=robot.createScreenCapture(rect); zip.putNextEntry(newZipEntry("test.jpg")); ImageIO.write(img,"jpg",zip); if(zip!=null)zip.close(); System.out.println("学生端口已经连接"); }catch(IOExceptionioe){ System.out.println("被控端:disconnect"); } }catch(IOExceptionioe){ System.out.println("连接出错"); }finally{ if(socket!=null){ try{ socket.close(); }catch(IOExceptione){ } } } } } }
发送鼠标信息:
/* *工具类:获取鼠标的信息并且发送给学生端 */ publicclassSendMouseMessageextendsThread{ privateintOPERATE_PORT=8001; privateServerSocketserver; privateSocketsocket; privateStringoperateStr; publicstaticvoidmain(String[]args) { newSendMouseMessage().start(); } publicSendMouseMessage(){ try{ server=newServerSocket(OPERATE_PORT); //JOptionPane.showMessageDialog(null,"已经开始监听"); }catch(IOExceptione1){ e1.printStackTrace(); } } //多线程 在无线的循环中监听客户端的 publicvoidrun() { while(true){ Pointpoint=MouseInfo.getPointerInfo().getLocation(); // operateStr="Movemouse,"+point.x+","+point.y; try{ socket=server.accept(); socket.setSoTimeout(1000000); DataOutputStreamoutput=newDataOutputStream(socket.getOutputStream()); output.write(operateStr.getBytes()); output.flush(); //刷行输出流,并且使所有缓冲的输出字节写出 output.close(); //关闭输出流且释放资源 System.out.println("INFO: "+operateStr); }catch(IOExceptione){ System.out.println("已经停止连接"); break; //断开连接的时候就停止无线循环 } } } }
客户端:
主程序:
importjava.util.concurrent.ExecutorService; importjava.util.concurrent.Executors; importcom.Tool.OperateMouse; importcom.Tool.ReceiveImages; publicclassReceiveBroderCast{ publicExecutorServiceexector; publicstaticStringIP="202.216.60.9"; publicstaticvoidmain(String[]args) { newReceiveBroderCast(IP); } publicReceiveBroderCast(StringIP){ exector=Executors.newFixedThreadPool(2); exector.execute(newReceiveImages(IP)); exector.execute(newOperateMouse(IP)); } }
接收截图代码:
/* *ly 2014-11-20 *该类用于接收教师端的屏幕信息,不包括鼠标 *使用socket() */ public classReceiveImagesextends Thread{ publicBorderInitframe; publicSocketsocket; publicStringIP; publicstaticvoidmain(String[]args){ newReceiveImages("202.216.60.7").start(); } publicReceiveImages(StringIP) { frame=newBorderInit(); this.IP=IP; } publicvoidrun(){ while(frame.getFlag()){ System.out.println("已经连接"+(System.currentTimeMillis()/1000)%24%60+"秒"); try{ socket=newSocket(IP,8002); DataInputStreamImgInput=newDataInputStream(socket.getInputStream()); ZipInputStreamimgZip=newZipInputStream(ImgInput); Imageimg=null; try{ imgZip.getNextEntry(); //到Zip文件流的开始处 img=ImageIO.read(imgZip);//按照字节读取Zip图片流里面的图片 frame.jlbImg.setIcon(newImageIcon(img)); frame.validate(); }catch(IOExceptione){e.printStackTrace();} try{ imgZip.close(); }catch(IOExceptione){ System.out.println("连接断开"); } try{ TimeUnit.MILLISECONDS.sleep(50);//接收图片间隔时间 }catch(InterruptedExceptionie){ ie.printStackTrace(); } }catch(IOExceptione){ e.printStackTrace(); }finally{ try{ socket.close(); }catch(IOExceptione){} } } } } classBorderInitextendsJFrame { privatestaticfinallongserialVersionUID=1L; publicJLabeljlbImg; privatebooleanflag; publicbooleangetFlag(){ returnthis.flag; } publicBorderInit() { this.flag=true; this.jlbImg=newJLabel(); this.setTitle("远程监控--IP:" +"--主题:"); this.setSize(400,400); //this.setUndecorated(true); //this.setAlwaysOnTop(true); //始终在最前面 this.add(jlbImg); this.setLocationRelativeTo(null); this.setExtendedState(Frame.MAXIMIZED_BOTH); this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); this.setVisible(true); this.validate(); //窗口关闭事件 this.addWindowListener(newWindowAdapter(){ publicvoidwindowClosing(WindowEvente){ flag=false; BorderInit.this.dispose(); System.out.println("窗体关闭"); System.gc(); //垃圾回收 } }); } }
接收鼠标信息并控制鼠标移动:
importjava.awt.AWTException; importjava.awt.Robot; importjava.io.BufferedInputStream; importjava.io.BufferedReader; importjava.io.DataInputStream; importjava.io.IOException; importjava.io.InputStream; importjava.net.Socket; importjavax.swing.JOptionPane; /* *学生端 控制鼠标和教师端一致 *该类 负责接收鼠标的信息 并且用robot.mouseMove()函数控制鼠标移动 */ publicclassOperateMouseextendsThread{ publicstaticvoidmain(String[]args) { newOperateMouse("202.116.60.7").start(); } privateSocketsocket; publicStringIP; privateintOPERATE_PORT=8001; privateRobotrobot; publicOperateMouse(StringIP) { this.IP=IP; } publicvoidrun(){ while(true){ try{ socket=newSocket(IP,OPERATE_PORT); robot=newRobot(); //获取鼠标移动的信息 DataInputStreamdataIn=newDataInputStream(socket.getInputStream()); Stringinfo=""; intr; while((r=dataIn.read())!=-1){ info+=""+(char)r; //把字节数组中所有元素都变为字符型 } dataIn.close(); System.out.println("数据流断开"+info); if(info!=null){ Strings[]=info.trim().split(","); if("Movemouse".equals(s[0].trim())); { if(s.length==3){ intx=Integer.parseInt(s[1].trim()); inty=Integer.parseInt(s[2].trim()); System.out.println("输出鼠标的信息"+x+" "+y); robot.mouseMove(x,y); } } } }catch(IOExceptione){ System.out.println("已断开连接"); break; }catch(AWTExceptione){ e.printStackTrace(); } } } }
希望本文所述对大家的Java程序设计有所帮助。