Java复习之知识点整理(二十二)--- 使用UDP搭建屏幕广播案例(一)教师端

37 篇文章 3 订阅
-----------------------------------------------------------------------------------
-----------------------一、Java项目和包结构如下:-----------------------
-----------------------------------------------------------------------------------







-----------------------------------------------------------------------------------
-----------------------二、 教师端Main类 :----------------------------------
-----------------------------------------------------------------------------------

public class TeacherMain {

	public static void main(String[] args) {		
		new Teacher().startTeacher();				
	}
}





-----------------------------------------------------------------------------------
-----------------------三、 教师端 :-------------------------------------------
-----------------------------------------------------------------------------------

public class Teacher {

	//机器人类
	private Robot robot;
	//截屏区域
	private Rectangle rect;
	
	public Teacher() {
		try {
			this.robot = new Robot();
			this.rect = new Rectangle(0, 0, 1366, 768);
		} catch (AWTException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	

	

	//开启UDP 教师端
	public void startTeacher()
	{		
		try {
			
			//1.创建udp套接字,并设定发送广播的端口
			DatagramSocket tSocket = new DatagramSocket(8888);
			//2.创建pack
			byte [] buf = new byte[1024 * 60 + 14];
			DatagramPacket tPack = new DatagramPacket(buf, buf.length); 
			//3.设定pack的目的地
			tPack.setAddress(InetAddress.getByName("192.168.0.107"));
			//4.设定pack的目标端口
			tPack.setPort(9999);
			
			//此处开始循环,每次循环时,发送一屏(多块==多UDP包)
			while(true)
			{
				//5.设定pack的内容
				//---5.1:捕捉屏幕			
				BufferedImage bufImg = catchScreen();
				//---5.2:压缩并获取屏幕字节数组
				byte [] allImgByteArr = zipImgGetBytes(bufImg);
				//---5.3:创建分块字节数组列表
				List<byte[]> blockList  = creatBlockList(allImgByteArr);
				System.out.println("bs.length:" + allImgByteArr.length + "---bs.blocks" + blockList.size());
				
				//6.循环发送
				for (byte[] bs : blockList) {
					//设定数据
					tPack.setData(bs);
					//发送
					tSocket.send(tPack);				
				}
				
				
				
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	
	/**
	 * 捕获一帧屏幕
	 */
	private BufferedImage catchScreen() {	
		
		return robot.createScreenCapture(rect);	
	}
	
	
	
	/**
	 * 压缩图片,获取图片字节
	 */
	private byte [] zipImgGetBytes(BufferedImage bufImg)
	{
		try {
			//创建内存字节流
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			//创建压缩流
			ZipOutputStream zos = new ZipOutputStream(baos);		
			//设定压缩入口
			zos.putNextEntry(new ZipEntry("xxx"));
			//将图片写入压缩流
			ImageIO.write(bufImg, "jpg", zos);
			zos.close();
			//获取压缩后图片的字节数组
			return baos.toByteArray();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	/**
	 * 获取分块字节数组集合
	 * 拆分字节数组为60K的块,并且添加固定报头
	 */
	public List<byte[]> creatBlockList(byte[] allImgByteArr)
	{
		//分块数组集合
		List<byte[]> blockList = new ArrayList<byte[]>();
		
		//1.设定标准块大小(包括报头)
		int standTotleBlockSize = 60 * 1024 + 14;
		
		//2.设定纯块大小,不含报头 60K
		int standBlockSize = 60 * 1024;
		
		
		//6.剩余字节数(最后一块)
		int remain = allImgByteArr.length % standBlockSize;
		//5.块数
		int blockCount = allImgByteArr.length / standBlockSize;
		
		if(remain != 0)
		{
			blockCount = allImgByteArr.length / standBlockSize + 1;
		}
		
		
		//设定读写缓冲区
		byte [] bs;  
		
		//7.开始分块(组装报文)
		//1.获取并写入唯一标识
		long flag = System.currentTimeMillis();
		
		for (int i = 0; i < blockCount; i++) {
			
			//7.设定当前分块字节数组,含报头(因为有最后一块不足的问题)
			byte [] curTotleByteArr = new byte[standTotleBlockSize];
			
			//8.设定当前分块字节数组,纯内容不含报头(因为有最后一块不足的问题)
			byte [] curByteArr = new byte[standBlockSize];
			
			//如果是最后一块,而且余数不为0,说明最后一块不足60K
			if(remain != 0 && i == (blockCount - 1))
			{
				curTotleByteArr = new byte[remain + 14];
				curByteArr = new byte[remain];
			}
			
			bs = Util.long2Bytes(flag);
			System.arraycopy(bs, 0, curTotleByteArr, 0, 8);
			
			//2.写入总块数
			curTotleByteArr[8] = (byte)blockCount;
			System.out.println("New Msg flag:" + flag +  "totle count" + curTotleByteArr[8]);
			
			//3.写入当前块序号 
			curTotleByteArr[9] = (byte)i;
			
			//4.写入内容长度
			bs = Util.int2Bytes(curByteArr.length);
			System.arraycopy(bs, 0, curTotleByteArr, 10, 4);
			
			//5.写入内容
			System.arraycopy(allImgByteArr, i * standBlockSize, curTotleByteArr, 14, curByteArr.length);
			
			//6.添加掉数组
			//System.out.println("");
			blockList.add(curTotleByteArr);
		}
			
		return blockList;
	}
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值