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;
}

  

 代码我测试没啥问题,自己跑的话需要自己更具项目本身做调整

 

posted @ 2020-07-02 11:03  憨憨青年  阅读(834)  评论(0编辑  收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css