java实现屏幕共享的⼩程序
最近在做软件软件⼯程的课程设计,做⼀个⽤于实验室的屏幕监控系统,参考各种前⼈代码,最后领悟之后要转换⾃⼰的代码,初学者都是这样模仿过来的。
说到屏幕监控系统,有教师断和学⽣端,教师端就是Server端,学⽣端就做Client端。系统⾥⽐较有趣的⼀个地⽅应该算是屏幕⼴播与屏幕监控吧,其余什么点名签到,锁屏,定时关机的,就相对来说简单点。
屏幕⼴播,在功能实现上⾯,说⽩了,就是教师端的机器不断截取屏幕信息,以图⽚的形式发送到每⼀个学⽣端的电脑上⾯,由此学⽣能够看见⽼师在电脑上的操作,这就是所谓的屏幕⼴播。
这⾥⾯有个⿇烦的地⽅,就是截取屏幕图⽚的时候,是没有⿏标信息。不过有两种解决办法:
①在发送截图信息时,在图⽚上绘制⼀个⿏标,这样在学⽣端就会有两个⿏标,学⽣端可以移动⾃⼰电脑上的⿏标。
②发送教师端的⿏标坐标到学⽣端上,学⽣端的电脑⿏标根据坐标信息实时移动,这⾥其实是涉及到控制的功能了,学⽣端就不能移动⿏标了。
屏幕监控相对棘⼿点,其实这是这包含俩功能:①教师监控所有学⽣电脑屏幕的功能;②教师控制某⼀个学⽣的电脑;因为涉及到并发,每个client都要实时的把屏幕信息发到教师端上,会有点⿇烦,不过还是可以实现。
下⾯是不带⿏标的屏幕共享功能,⽐较简单,有待完善,不过可以作为⼀个⼯具类在后⾯集成使⽤。后⾯补充了把⿏标画上去的代码,只需要3⾏。
⾸先是教师端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.ServerSocket;
import java.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[])
{
入门的java游戏小程序
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 = DefaultToolkit().getScreenSize();  //获取主屏幕的⼤⼩
rect = new Rectangle(screen);                          //构造屏幕⼤⼩的矩形
}
@Override
public void run()
{
//实时等待接收截屏消息
while(true)
{
try{
socket = serverSocket.accept();
System.out.println("学⽣端⼝已经连接");
ZipOutputStream zip = new ZipOutputStream(new OutputStream()));    zip.setLevel(9);    //设置压缩级别
BufferedImage img = ateScreenCapture(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.Socket;
import urrent.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() {
Flag()){
try {
socket = new Socket(IP,8000);
DataInputStream ImgInput = new InputStream());
ZipInputStream imgZip = new ZipInputStream(ImgInput);
Image img = ad(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("窗体关闭");
<();    //垃圾回收
}
});
}
}
很晚了,从未成品中抽取了这么个⼩功能,因为答应某位童鞋给链接的,距离成品还有很多要写,后续补上吧。
后续补充:
把⿏标画到屏幕截图的⽅法,在SendScreenImg类中 BufferedImage img = ateScreenCapture(rect);后⾯,添加下⾯三⾏代码:
BufferedImage cursor= ad(new File("img/cursor.png"));  //把⿏标加载到缓存中
Point p= PointerInfo().getLocation();              //获取⿏标坐标
嗯,记得在⼯程下⾯建⽴⼀个img⽂件夹,在⽂件夹中放置名为cursor.png的⿏标图⽚,⼀定要png格式的,要求底⾊透明,可以去下载,也可以⾃⼰p图。
给张运⾏时候的截图(按理说应该是有3个⿏标的,但是QQ截图也是没有的⿏标):
本⽂出⾃博客园。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。