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程序设计有所帮助。