在軟件工程課程設計中,需要構建一套「教師端(Server)廣播屏幕,學生端(Client)實時接收顯示」的屏幕共享系統。核心難點在於:高頻截圖、圖片壓縮傳輸、多客戶端併發、鼠標軌跡同步。本文提供一個可運行的 MVP(最小可行性產品)代碼結構,採用 Robot 截屏 + Socket 傳輸 + Zip 壓縮 + Swing 顯示的經典技術棧。
ServerSocket 監聽端口,循環 accept() 接收連接 → Robot.createScreenCapture() 截屏 → ImageIO.write() 編碼 JPG → ZipOutputStream 壓縮 → 輸出流發送。Socket 連接 Server → ZipInputStream 解壓 → ImageIO.read() 解碼 → JLabel.setIcon() 刷新顯示 → 定時輪詢(50ms)實現準實時。public class SendScreenImg extends Thread {
public static final int PORT = 8000;
private final ServerSocket serverSocket;
private final Robot robot;
private final Rectangle screenRect;
public SendScreenImg() throws Exception {
serverSocket = new ServerSocket(PORT);
serverSocket.setSoTimeout(864000000); // 10天超時,防止accept阻塞
robot = new Robot();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
screenRect = new Rectangle(screenSize); // 全屏矩形區域
}
@Override
public void run() {
while (true) {
try (Socket client = serverSocket.accept();
ZipOutputStream zos = new ZipOutputStream(new DataOutputStream(client.getOutputStream()))) {
zos.setLevel(9); // 最高壓縮比
BufferedImage img = robot.createScreenCapture(screenRect);
zos.putNextEntry(new ZipEntry("screen.jpg"));
ImageIO.write(img, "jpg", zos);
zos.closeEntry();
} catch (IOException e) {
System.err.println("客戶端斷開或傳輸異常:" + e.getMessage());
}
}
}
public static void main(String[] args) {
try { new SendScreenImg().start(); }
catch (Exception e) { e.printStackTrace(); }
}
}
public class ReceiveImages extends Thread {
private final String serverIp;
private final BorderInit frame; // 自定義 JFrame 容器
public ReceiveImages(String serverIp) {
this.serverIp = serverIp;
this.frame = new BorderInit();
}
@Override
public void run() {
while (frame.isRunning()) {
try (Socket socket = new Socket(serverIp, 8000);
ZipInputStream zis = new ZipInputStream(socket.getInputStream())) {
zis.getNextEntry(); // 定位到壓縮流入口
Image img = ImageIO.read(zis); // 直接解碼
frame.updateImage(img); // 線程安全更新 UI
TimeUnit.MILLISECONDS.sleep(50); // 控制幀率 ~20fps
} catch (IOException | InterruptedException e) {
System.err.println("連接異常,重試中..."); // 實際應用應加重試邏輯
}
}
}
}
// UI 容器類
class BorderInit extends JFrame {
private final JLabel imgLabel = new JLabel();
private volatile boolean running = true;
public BorderInit() {
setTitle("遠程屏幕監控");
setSize(800, 600);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
add(imgLabel);
setLocationRelativeTo(null);
setExtendedState(MAXIMIZED_BOTH);
setVisible(true);
addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent e) { running = false; }
});
}
public void updateImage(Image img) { imgLabel.setIcon(new ImageIcon(img)); }
public boolean isRunning() { return running; }
}
| 難點 | 現狀 | 優化建議 |
|---|---|---|
| 鼠標軌跡缺失 | Robot.createScreenCapture 不捕獲鼠標 | 方案A:服務端疊加繪製鼠標圖標;方案B:單獨傳輸座標,客戶端渲染(涉及遠程控制) |
| 帶寬佔用高 | 全量 JPG 壓縮,未做差幀/脏矩形檢測 | 引入 BufferedImage.getSubimage() 僅傳輸變化區域;或集成 H.264/VP8 視頻編碼 |
| 多客戶端併發 | 單線程循環 accept,串行處理 | 使用線程池 ExecutorService 或 NIO (Netty) 實現多路複用 |
| 延遲與幀率 | 固定 50ms 轮询,網絡抖動無緩衝 | 客戶端引入緩衝隊列,自適應幀率;服務端推模式替代拉模式 |
本文實現了基礎的「單向屏幕廣播」功能,代碼結構清晰,適合作為教學 Demo 或二次開發基礎。生產環境建議:
java.awt.Robot 模擬輸入)。