Socket通信

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

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

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

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

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

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

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

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

屏幕监控相对棘手点,其实这是这包含俩功能:

①教师监控所有学生电脑屏幕的功能;

②教师控制某一个学生的电脑;

因为涉及到并发,每个client都要实时的把屏幕信息发到教师端上,会有点麻烦,不过还是可以实现。

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

首先是教师端Server:

  
  
  1. package Test;
  2.  
  3. import java.awt.Dimension;
  4. import java.awt.Rectangle;
  5. import java.awt.Robot;
  6. import java.awt.Toolkit;
  7. import java.awt.image.BufferedImage;
  8. import java.io.DataOutputStream;
  9. import java.io.IOException;
  10. import java.net.ServerSocket;
  11. import java.net.Socket;
  12. import java.util.zip.ZipEntry;
  13. import java.util.zip.ZipOutputStream;
  14.  
  15. import javax.imageio.ImageIO;
  16.  
  17. /*
  18.  * ly  2014-11-20
  19.  * 该类实时发送截屏消失,多线程实现,不包含鼠标信息,且没有做对每个Client做优化处理
  20.  */
  21. public  class SendScreenImg extends Thread
  22. {
  23.     public static int SERVERPORT=8000;
  24.     private ServerSocket serverSocket;
  25.     private Robot robot;
  26.     public  Dimension screen;
  27.     public Rectangle rect ;
  28.     private Socket socket; 
  29.      
  30.     public static void main(String args[])
  31.     {
  32.         new SendScreenImg(SERVERPORT).start();
  33.     }
  34.      
  35.     //构造方法  开启套接字连接      机器人robot   获取屏幕大小
  36.     public SendScreenImg(int SERVERPORT)
  37.     {
  38.         try {
  39.             serverSocket = new ServerSocket(SERVERPORT);
  40.             serverSocket.setSoTimeout(864000000);
  41.             robot = new Robot();
  42.         } catch (Exception e) {
  43.             e.printStackTrace();
  44.         }
  45.         screen = Toolkit.getDefaultToolkit().getScreenSize();  //获取主屏幕的大小
  46.         rect = new Rectangle(screen);                          //构造屏幕大小的矩形
  47.     }
  48.      
  49.     @Override
  50.     public void run() 
  51.     {
  52.         //实时等待接收截屏消息
  53.         while(true)
  54.         {
  55.             try{
  56.                 socket = serverSocket.accept();
  57.                 System.out.println("学生端口已经连接");
  58.                 ZipOutputStream zip = new ZipOutputStream(new DataOutputStream(socket.getOutputStream()));
  59.                 zip.setLevel(9);     //设置压缩级别
  60.                  
  61.                 BufferedImage img = robot.createScreenCapture(rect);
  62.                 zip.putNextEntry(new ZipEntry("test.jpg"));
  63.                 ImageIO.write(img, "jpg", zip);
  64.                 if(zip!=null)zip.close();
  65.                 System.out.println("Client正在实时连接");
  66.                 
  67.             } catch (IOException ioe) {
  68.                 System.out.println("连接断开");
  69.             } finally {
  70.                 if (socket != null) {
  71.                     try {
  72.                         socket.close();
  73.                     } catch (IOException e) {e.printStackTrace();}
  74.                 }
  75.             }
  76.         }
  77.     }
  78. }

然后是学生端Client:

  
  
  1. package Test;
  2. import java.awt.Frame;
  3. import java.awt.Image;
  4. import java.awt.event.WindowAdapter;
  5. import java.awt.event.WindowEvent;
  6. import java.io.DataInputStream;
  7. import java.io.IOException;
  8. import java.net.Socket;
  9. import java.util.concurrent.TimeUnit;
  10. import java.util.zip.ZipInputStream;
  11. import javax.imageio.ImageIO;
  12. import javax.swing.ImageIcon;
  13. import javax.swing.JFrame;
  14. import javax.swing.JLabel;
  15. /*
  16.  * ly  2014-11-20
  17.  * 该类用于接收教师端的屏幕信息,不包括鼠标,待优化
  18.  */
  19. public  class ReceiveImages extends  Thread{
  20.     public BorderInit frame ;
  21.     public Socket socket;
  22.     public String IP;
  23.      
  24.     public static void main(String[] args){
  25.         new ReceiveImages(new BorderInit(), "127.0.0.1").start();
  26.     }
  27.     public ReceiveImages(BorderInit frame,String IP)
  28.     {
  29.         this.frame = frame;
  30.         this.IP=IP;
  31.     }
  32.      
  33.     public void run() {
  34.         while(frame.getFlag()){
  35.             try {
  36.                 socket = new Socket(IP,8000);
  37.                 DataInputStream ImgInput = new DataInputStream(socket.getInputStream());
  38.                 ZipInputStream imgZip = new ZipInputStream(ImgInput);
  39.                  
  40.                 imgZip.getNextEntry();             //到Zip文件流的开始处
  41.                 Image img = ImageIO.read(imgZip);  //按照字节读取Zip图片流里面的图片
  42.                 frame.jlbImg.setIcon(new ImageIcon(img));
  43.                 System.out.println("连接第"+(System.currentTimeMillis()/1000)%24%60+"秒");
  44.                 frame.validate();
  45.                 TimeUnit.MILLISECONDS.sleep(50);// 接收图片间隔时间
  46.                 imgZip.close();
  47.                  
  48.             } catch (IOException | InterruptedException e) {
  49.                 System.out.println("连接断开");
  50.             }finally{
  51.                 try {
  52.                     socket.close();
  53.                 } catch (IOException e) {}  
  54.             }       
  55.         }   
  56.     }
  57. }
  58.  
  59. //Client端窗口辅助类,专门用来显示从教师端收到的屏幕信息
  60. class BorderInit extends JFrame
  61. {
  62.     private static final long serialVersionUID = 1L;
  63.     public JLabel jlbImg;
  64.     private boolean flag;
  65.     public boolean getFlag(){
  66.         return this.flag;
  67.     }
  68.     public BorderInit()
  69.     {
  70.         this.flag=true;
  71.         this.jlbImg = new JLabel();
  72.         this.setTitle("远程监控--IP:"  + "--主题:" );
  73.         this.setSize(400, 400);
  74.         //this.setUndecorated(true);  //全屏显示,测试时最好注释掉
  75.         //this.setAlwaysOnTop(true);  //显示窗口始终在最前面
  76.         this.add(jlbImg);
  77.         this.setLocationRelativeTo(null);
  78.         this.setExtendedState(Frame.MAXIMIZED_BOTH);
  79.         this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
  80.         this.setVisible(true);
  81.         this.validate();
  82.      
  83.         //窗口关闭事件
  84.         this.addWindowListener(new WindowAdapter() {
  85.             public void windowClosing(WindowEvent e) {
  86.                 flag=false;
  87.                 BorderInit.this.dispose();
  88.                 System.out.println("窗体关闭");
  89.                 System.gc();    //垃圾回收
  90.             }
  91.         });
  92.     }
  93. }

这里就从未成品中抽取了这么个小功能,距离成品还有很多要写,感兴趣的朋友可以在此基础上加以完善。

希望本文所述对大家的Java程序设计有所帮助。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值