java使用Socket長連接實現遠程桌面實時查看


一.效果

1.1 里面有三個java文件

BorderInit.java               //抽出的一個方法定義容器
ReceiveImages.java     //用於接收服務器端發送的信息
SendScreen.java          //用於獲取當前平台的頁面,通過Socket發送

 

1.2啟動順序:SendScreen.java  ------》ReceiveImages.java

(1)啟動SendScreen.java

 

 (2)啟動ReceiveImages.java

 

 (3)點擊SendScreen.java生成的容器中的開始直播

 

 二.demo代碼

(1)BorderInit.java         

package demo;

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;

//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:"+"127.0.0.1");
		this.setSize(800, 600);
		this.setAlwaysOnTop(false);  // true顯示窗口始終在最前面
		this.add(jlbImg);
		this.setLocationRelativeTo(null);//如果組件當前未顯示或者  為 null,則此窗口將置於屏幕的中央。
		this.setExtendedState(Frame.MAXIMIZED_BOTH);//Swing中設置窗口最大化
		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();  
			}
		});
	}
}

  

   
(2)ReceiveImages.java    

package demo;

import java.awt.Image;
import java.io.*;
import java.net.Socket;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipInputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

/*
 * @KnuthChao 20150625
 * 用於接收服務器端發送的信息,沒有寫多線程和鼠標的錄制,后期有空 *會加上去;
 */
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;
	}
	//實現run方法
	public void run() {
		while(frame.getFlag()){
			try {
				socket = new Socket(IP,12122);
				DataInputStream ImgInput = new DataInputStream(socket.getInputStream());
				System.out.println("ImgInput:"+ImgInput);
				ZipInputStream imgZip = new ZipInputStream(ImgInput);//解析zip文件

				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(1);// 接收圖片間隔時間
				imgZip.close();


			} catch (IOException e) {
				System.out.println("連接斷開");
			} catch (InterruptedException e) {
				System.out.println("連接斷開");
			}finally{
				try {
					socket.close();
				} catch (IOException e) {}  
			}       
		}  
	}
}

  


(3)SendScreen.java         

package demo;

import javax.swing.DefaultListModel;
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 java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
/**
 *
 * @author Knuth
 */
public class SendScreen extends javax.swing.JFrame {

	public static int SERVERPORT=12122;
	private ServerSocket serverSocket;
/**
 * Robot 的主要目的是便於 Java 平台實現自動測試
 * 使用該類生成輸入事件與將事件發送到 AWT 事件隊列或 AWT 組件的區別在於:事件是在平台的本機輸入隊列中生成的
 */
	private Robot robot;
	public  Dimension screen;
	public Rectangle rect ;
	private Socket socket; 
	//創建dlmsend列表
	DefaultListModel dlmsend = new DefaultListModel();

	public SendScreen(int SERVERPORT) {
		initComponents();
		jList1.setModel(dlmsend);
		try {
			serverSocket = new ServerSocket(SERVERPORT);
			//設置超時時間
			serverSocket.setSoTimeout(864000);
			robot = new Robot();
		} catch (Exception e) {
			e.printStackTrace();
		}

		screen = Toolkit.getDefaultToolkit().getScreenSize();  //獲取主屏幕的大小

		rect = new Rectangle(screen);                          //構造屏幕大小的矩形

	}                         
	private void initComponents() {

		jScrollPane1 = new javax.swing.JScrollPane(); //帶滾動條的控制面板
		jList1 = new javax.swing.JList();
		jButton1 = new javax.swing.JButton();
		jButton2 = new javax.swing.JButton();

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);//退出時關閉

		jScrollPane1.setViewportView(jList1);

		jButton1.setText("開始廣播");
		jButton1.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton1ActionPerformed(evt);
			}
		});

		jButton2.setText("結束廣播");
		jButton2.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton2ActionPerformed(evt);
			}
		});

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(
				layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(layout.createSequentialGroup()
						.addGap(28, 28, 28)
						.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
								.addGroup(layout.createSequentialGroup()
										.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 389, javax.swing.GroupLayout.PREFERRED_SIZE)
										.addContainerGap(24, Short.MAX_VALUE))
								.addGroup(layout.createSequentialGroup()
										.addComponent(jButton1)
										.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
										.addComponent(jButton2)
										.addGap(40, 40, 40))))
				);
		layout.setVerticalGroup(
				layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(layout.createSequentialGroup()
						.addGap(24, 24, 24)
						.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 185, javax.swing.GroupLayout.PREFERRED_SIZE)
						.addGap(62, 62, 62)
						.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
								.addComponent(jButton1)
								.addComponent(jButton2))
						.addContainerGap(61, Short.MAX_VALUE))
				);

		pack();
	}// </editor-fold>                        

	private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
		// TODO add your handling code here:
		dlmsend.addElement("教師端開始廣播!");

		Thread t = new  reThread();
		t.start();
	}                                        

	private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         

		try {
			// TODO add your handling code here:
			dlmsend.addElement("廣播結束");
			socket.close();
			Thread t = new  reThread();
			//t.stop();//強行停止線程 已被廢棄掉該方法
			t.interrupt();//方法不能直接停止線程,只是給線程打上一個需要停止的標記,具體什么時候停 不確定
		} catch (IOException ex) {
			Logger.getLogger(SendScreen.class.getName()).log(Level.SEVERE, null, ex);
		}
	}                                        



	class reThread extends Thread {

		public void run(){

			while(true)
			{
				try{
					//接收一個套接字中已建立的連接
					socket = serverSocket.accept();
					dlmsend.addElement("學生端口已經連接");
					ZipOutputStream zip = new ZipOutputStream(new DataOutputStream(socket.getOutputStream()));
					zip.setLevel(0);     //設置壓縮級別,java共8個還是11個壓縮級別?



					BufferedImage img = robot.createScreenCapture(rect);
					zip.putNextEntry(new ZipEntry("test.jpg"));
					ImageIO.write(img,"jpg",zip);
					if(zip!=null)zip.close();
					dlmsend.addElement("Client正在實時連接");
					dlmsend.addElement("連接第"+(System.currentTimeMillis()/1000)%24%60+"秒");
				} catch (IOException ioe) {
					dlmsend.addElement("連接斷開");

				} finally {
					if (socket != null) {
						try {
							socket.close();
						} catch (IOException e) {e.printStackTrace();}
					}
				}
			}
		}
	}

	public static void main(String args[]) {

		try {
			//獲得系統中可用bai外觀
			for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
				if ("Nimbus".equals(info.getName())) {
					//設置baiUI
					javax.swing.UIManager.setLookAndFeel(info.getClassName());
					break;
				}
			}
		} catch (ClassNotFoundException ex) {
			java.util.logging.Logger.getLogger(SendScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		} catch (InstantiationException ex) {
			java.util.logging.Logger.getLogger(SendScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		} catch (IllegalAccessException ex) {
			java.util.logging.Logger.getLogger(SendScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		} catch (javax.swing.UnsupportedLookAndFeelException ex) {
			java.util.logging.Logger.getLogger(SendScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		}

		/* Create and display the form */
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				new SendScreen(SERVERPORT).setVisible(true);
			}
		});
	}
	// Variables declaration - do not modify                     
	private javax.swing.JButton jButton1;
	private javax.swing.JButton jButton2;
	private javax.swing.JList jList1;
	private javax.swing.JScrollPane jScrollPane1;
}

  

 代碼我測試沒啥問題,自己跑的話需要自己更具項目本身做調整

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM