闲来无事 ,实现了一个几年前的想法 屏幕监控,使用udp传输 ,udp传输的大小有限制
通过优化实现了屏幕监控
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import org.junit.Test;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
public class UdpTest {
private byte[] copy(byte[] a, byte[] b) {
byte[] c = new byte[a.length + b.length];
System.arraycopy(a, 0, c, 0, a.length);
System.arraycopy(b, 0, c, a.length, b.length);
return c;
}
private boolean startWith(byte[] aa, byte[] start) {
for (int i = 0; i < start.length; i++) {
if (i > aa.length - 1) {
return false;
}
if (aa[i] != start[i]) {
return false;
}
}
return true;
}
private byte[] captureScreen() throws AWTException, IOException {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screenRectangle = new Rectangle(screenSize);
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(screenRectangle);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(image, "png", bos);
return bos.toByteArray();
}
/**
* 客户端发送
* @throws IOException
*/
@Test
public void client() throws IOException {
java.util.Timer qTimer = new java.util.Timer();
qTimer.schedule(new TimerTask() {
@Override
public void run() {
try {
byte[] bytes = captureScreen();
send(bytes);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}, new Date(), 500);
System.in.read();
}
@Test
public void sendFile() throws Exception {
byte[] data = FileUtil.readBytes("D:\\aa.jpg");
send(data);
}
public void send(byte[] data) throws Exception {
// byte[] data = FileUtil.readBytes("C:\\Users\\DELL\\Pictures\\bb.jpeg");
// byte[] data = FileUtil.readBytes("C:\\Users\\DELL\\Pictures\\timg.jpg");
byte[] header = new byte[100];
String obj = "length:" + data.length + ":end";
System.out.println("all:" + obj);
byte[] bytes = obj.getBytes();
System.arraycopy(bytes, 0, header, 0, bytes.length);
byte[] copy = copy(header, data);
DatagramSocket datagramSocket = new DatagramSocket();
int ced = 0;
byte[] c = new byte[50 * 1024];
while (true) {
int sy = copy.length - ced;
if (sy <= 0) {
break;
}
int min = Math.min(sy, c.length);
System.arraycopy(copy, ced, c, 0, min);
DatagramPacket dataGramPacket = new DatagramPacket(c, min, InetAddress.getByName("127.0.0.1"), 9999);
datagramSocket.send(dataGramPacket);
ced += min;
System.out.println("send" + ced);
TimeUnit.MICROSECONDS.sleep(1); //限制传输速度 不然容易丢包
}
}
/**
* 服务端接收
* @throws Exception
*/
@Test
public void receive() throws Exception {
byte[] header = "length".getBytes();
byte[] bs = new byte[1024 * 1024];
DatagramPacket dp = new DatagramPacket(bs, bs.length);
DatagramSocket datagramSocket = new DatagramSocket(9999);
JFrame frame = new JFrame("title");
frame.setMinimumSize(new Dimension(500, 500));
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ByteArrayOutputStream bao = new ByteArrayOutputStream();
int ed = 0;
boolean x = false;
int len = 0;
while (true) {
datagramSocket.receive(dp);
boolean b = startWith(dp.getData(), header);
if (!x) {
String s = new String(dp.getData(), 0, 100);
String s1 = StrUtil.subBetween(s, "length:", ":end");
System.out.println("sss+" + s1);
len = Integer.parseInt(s1);
x = true;
}
if (x) {
if (ed == 0) {
int len1 = dp.getLength() - 100;
bao.write(dp.getData(), 100, len1);
ed += len1;
} else {
bao.write(dp.getData(), 0, dp.getLength());
ed += dp.getLength();
}
} else {
System.out.println("not-length");
}
if (bao.size() >= len) {
showImg(bao.toByteArray(), frame);
bao.reset();
x = false;
ed = 0;
}
System.out.println("bbbb" + dp.getLength());
}
}
ImageLabel label = null;
public void showImg(byte[] bytes, JFrame frame) throws IOException {
ByteArrayInputStream in = new ByteArrayInputStream(bytes); //将b作为输入流;
BufferedImage image = null;
try {
image = ImageIO.read(in);
} catch (IOException e) {
e.printStackTrace();
return;
}
// Image scaledInstance = image.getScaledInstance(800, 500, Image.SCALE_SMOOTH);
ImageIcon icon = new ImageIcon(image);
if (label != null) {
label.setIcon(icon);
} else {
label = new ImageLabel(icon);
label.setLocation(0, 0);
frame.getContentPane().add(label);
label.validate();
}
label.validate();
frame.validate(); //动态添加或者删除某些控件后,为了实时展现操作后的结果
//Frame.pack();//这个方法的作用就是:根据窗口里面的布局及组件的preferedSize来确定frame的最佳大小。
}
public static class ImageLabel extends JLabel {
public ImageLabel(ImageIcon icon) {
setSize(icon.getImage().getWidth(null),
icon.getImage().getHeight(null));
setIcon(icon);
setIconTextGap(0);
setBorder(null);
setText(null);
setOpaque(false);
}
}
}