本文實例講述了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程式設計有幫助。