欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java实现屏幕共享功能实例分析

程序员文章站 2024-03-02 13:53:10
本文实例讲述了java实现屏幕共享功能的方法。分享给大家供大家参考。具体分析如下: 最近在做软件软件工程的课程设计,做一个用于实验室的屏幕监控系统,参考各种前人代码,最后...

本文实例讲述了java实现屏幕共享功能的方法。分享给大家供大家参考。具体分析如下:

最近在做软件软件工程的课程设计,做一个用于实验室的屏幕监控系统,参考各种前人代码,最后领悟之后要转换自己的代码,初学者都是这样模仿过来的。

说到屏幕监控系统,有教师端和学生端,教师端就是server端,学生端就做client端。系统里比较有趣的一个地方应该算是屏幕广播与屏幕监控吧,其余什么点名签到,锁屏,定时关机的,就相对来说简单点。

屏幕广播,在功能实现上面,说白了,就是教师端的机器不断截取屏幕信息,以图片的形式发送到每一个学生端的电脑上面,由此学生能够看见老师在电脑上的操作,这就是所谓的屏幕广播。

这里面有个麻烦的地方,就是截取屏幕图片的时候,是没有鼠标信息。不过有两种解决办法:

①在发送截图信息时,在图片上绘制一个鼠标,这样在学生端就会有两个鼠标,学生端可以移动自己电脑上的鼠标。

②发送教师端的鼠标坐标到学生端上,学生端的电脑鼠标根据坐标信息实时移动,这里其实是涉及到控制的功能了,学生端就不能移动鼠标了。

屏幕监控相对棘手点,其实这是这包含俩功能:
①教师监控所有学生电脑屏幕的功能;
②教师控制某一个学生的电脑;
因为涉及到并发,每个client都要实时的把屏幕信息发到教师端上,会有点麻烦,不过还是可以实现。

这里暂时实现了不带鼠标的屏幕共享功能,比较简单,有待完善,不过可以作为一个工具类在后面集成使用。

首先是教师端server:

复制代码 代码如下:
package test;
 
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:

复制代码 代码如下:
package test;
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程序设计有所帮助。