java实现屏幕共享功能实例分析
本文实例讲述了java实现屏幕共享功能的方法。分享给大家供大家参考。具体分析如下:
最近在做软件软件工程的课程设计,做一个用于实验室的屏幕监控系统,参考各种前人代码,最后领悟之后要转换自己的代码,初学者都是这样模仿过来的。
说到屏幕监控系统,有教师端和学生端,教师端就是server端,学生端就做client端。系统里比较有趣的一个地方应该算是屏幕广播与屏幕监控吧,其余什么点名签到,锁屏,定时关机的,就相对来说简单点。
屏幕广播,在功能实现上面,说白了,就是教师端的机器不断截取屏幕信息,以图片的形式发送到每一个学生端的电脑上面,由此学生能够看见老师在电脑上的操作,这就是所谓的屏幕广播。
这里面有个麻烦的地方,就是截取屏幕图片的时候,是没有鼠标信息。不过有两种解决办法:
①在发送截图信息时,在图片上绘制一个鼠标,这样在学生端就会有两个鼠标,学生端可以移动自己电脑上的鼠标。
②发送教师端的鼠标坐标到学生端上,学生端的电脑鼠标根据坐标信息实时移动,这里其实是涉及到控制的功能了,学生端就不能移动鼠标了。
屏幕监控相对棘手点,其实这是这包含俩功能:
①教师监控所有学生电脑屏幕的功能;
②教师控制某一个学生的电脑;
因为涉及到并发,每个client都要实时的把屏幕信息发到教师端上,会有点麻烦,不过还是可以实现。
这里暂时实现了不带鼠标的屏幕共享功能,比较简单,有待完善,不过可以作为一个工具类在后面集成使用。
首先是教师端server:
import java.awt.dimension;
import java.awt.rectangle;
import java.awt.robot;
import java.awt.toolkit;
import java.awt.image.bufferedimage;
import java.io.dataoutputstream;
import java.io.ioexception;
import java.net.serversocket;
import java.net.socket;
import java.util.zip.zipentry;
import java.util.zip.zipoutputstream;
import javax.imageio.imageio;
/*
* ly 2014-11-20
* 该类实时发送截屏消失,多线程实现,不包含鼠标信息,且没有做对每个client做优化处理
*/
public class sendscreenimg extends thread
{
public static int serverport=8000;
private serversocket serversocket;
private robot robot;
public dimension screen;
public rectangle rect ;
private socket socket;
public static void main(string args[])
{
new sendscreenimg(serverport).start();
}
//构造方法 开启套接字连接 机器人robot 获取屏幕大小
public sendscreenimg(int serverport)
{
try {
serversocket = new serversocket(serverport);
serversocket.setsotimeout(864000000);
robot = new robot();
} catch (exception e) {
e.printstacktrace();
}
screen = toolkit.getdefaulttoolkit().getscreensize(); //获取主屏幕的大小
rect = new rectangle(screen); //构造屏幕大小的矩形
}
@override
public void run()
{
//实时等待接收截屏消息
while(true)
{
try{
socket = serversocket.accept();
system.out.println("学生端口已经连接");
zipoutputstream zip = new zipoutputstream(new dataoutputstream(socket.getoutputstream()));
zip.setlevel(9); //设置压缩级别
bufferedimage img = robot.createscreencapture(rect);
zip.putnextentry(new zipentry("test.jpg"));
imageio.write(img, "jpg", zip);
if(zip!=null)zip.close();
system.out.println("client正在实时连接");
} catch (ioexception ioe) {
system.out.println("连接断开");
} finally {
if (socket != null) {
try {
socket.close();
} catch (ioexception e) {e.printstacktrace();}
}
}
}
}
}
然后是学生端client:
import java.awt.frame;
import java.awt.image;
import java.awt.event.windowadapter;
import java.awt.event.windowevent;
import java.io.datainputstream;
import java.io.ioexception;
import java.net.socket;
import java.util.concurrent.timeunit;
import java.util.zip.zipinputstream;
import javax.imageio.imageio;
import javax.swing.imageicon;
import javax.swing.jframe;
import javax.swing.jlabel;
/*
* ly 2014-11-20
* 该类用于接收教师端的屏幕信息,不包括鼠标,待优化
*/
public class receiveimages extends thread{
public borderinit frame ;
public socket socket;
public string ip;
public static void main(string[] args){
new receiveimages(new borderinit(), "127.0.0.1").start();
}
public receiveimages(borderinit frame,string ip)
{
this.frame = frame;
this.ip=ip;
}
public void run() {
while(frame.getflag()){
try {
socket = new socket(ip,8000);
datainputstream imginput = new datainputstream(socket.getinputstream());
zipinputstream imgzip = new zipinputstream(imginput);
imgzip.getnextentry(); //到zip文件流的开始处
image img = imageio.read(imgzip); //按照字节读取zip图片流里面的图片
frame.jlbimg.seticon(new imageicon(img));
system.out.println("连接第"+(system.currenttimemillis()/1000)%24%60+"秒");
frame.validate();
timeunit.milliseconds.sleep(50);// 接收图片间隔时间
imgzip.close();
} catch (ioexception | interruptedexception e) {
system.out.println("连接断开");
}finally{
try {
socket.close();
} catch (ioexception e) {}
}
}
}
}
//client端窗口辅助类,专门用来显示从教师端收到的屏幕信息
class borderinit extends jframe
{
private static final long serialversionuid = 1l;
public jlabel jlbimg;
private boolean flag;
public boolean getflag(){
return this.flag;
}
public borderinit()
{
this.flag=true;
this.jlbimg = new jlabel();
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(new windowadapter() {
public void windowclosing(windowevent e) {
flag=false;
borderinit.this.dispose();
system.out.println("窗体关闭");
system.gc(); //垃圾回收
}
});
}
}
这里就从未成品中抽取了这么个小功能,距离成品还有很多要写,感兴趣的朋友可以在此基础上加以完善。
希望本文所述对大家的java程序设计有所帮助。
上一篇: 什么情况下需要创建MySQL索引?