IT十八掌作业_java基础第十八天_项目完善
感谢大家对IT十八掌大数据的支持,今天的作业如下:
1.QQ完成
2.使用DatagramSocket实现屏广
Server : //完善代码,区域缩小 2.合包
客户端 : JFrame ,ImageIcon
-------------------------------------------------------------------------------------------
项目源码:
package com.it18zhang.udp.screenbroadcast;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;
/**
* 客户端接收线程
*/
public class ClientReceiverThread extends Thread {
//存放所有frame的集合
private Map<Long, Map<Integer,FrameUnit>> frames = new HashMap<Long,Map<Integer,FrameUnit>>();
// 客户端窗口
private ClientUI ui;
private DatagramSocket sock;
public ClientReceiverThread(ClientUI ui) {
this.ui = ui;
try {
sock = new DatagramSocket(8889);
}
catch (Exception e) {
}
}
public void run() {
try {
// 缓冲区
byte[] buf = new byte[60 * 1024];
DatagramPacket pack = new DatagramPacket(buf, buf.length);
while (true) {
//接收数据,收到了一帧画面的一个单元。
sock.receive(pack);
FrameUnit unit = new FrameUnit(pack);
//包含gid
Map<Integer,FrameUnit> old = null ;
if(frames.containsKey(unit.getGid())){
//取出原有的
old = frames.get(unit.getGid());
old.put(unit.getIndex(), unit);
}
//不包含
else{
old = new HashMap<Integer,FrameUnit>();
old.put(unit.getIndex(), unit);
frames.put(unit.getGid(),old) ;
}
//是否收集齐全所有的FrameUnit
int count = unit.getCount() ;
int receiveCount = frames.get(unit.getGid()).size();
//齐了
if(count == receiveCount){
byte[] p_w_picpath = mergeImage(old);
ui.refreshImage(p_w_picpath);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
/**
* 使用gzip进行解压处理
*/
public byte[] gzipDecompress(byte[] srcdata, int offset, int length) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//
ByteArrayInputStream bais = new ByteArrayInputStream(srcdata,offset, length);
GZIPInputStream gzis = new GZIPInputStream(bais);
byte[] buf = new byte[1024];
int len = 0;
while ((len = gzis.read(buf)) != -1) {
baos.write(buf, 0, len);
}
gzis.close();
return baos.toByteArray();
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 合成所有FrameUnit中的rawData,形成byte[]
*/
public byte[] mergeImage(Map<Integer,FrameUnit> units){
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for(int i = 0 ; i < units.size() ; i ++){
FrameUnit u = units.get(i);
baos.write(u.getRawData());
}
return baos.toByteArray() ;
}
catch (Exception e) {
e.printStackTrace();
}
return null ;
}
}
package com.it18zhang.udp.screenbroadcast;
import java.awt.p_w_picpath.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class ClientUI extends JFrame{
private JLabel label ;
private ImageIcon icon ;
public ClientUI(){
ini();
}
/**
* 初始化
*/
private void ini() {
this.setBounds(0,0, 1366, 768);
this.setLayout(null);
//label
label = new JLabel();
label.setBounds(0, 0, 1366, 768);
label.setLayout(null);
//
icon = new ImageIcon("d:/Koala.jpg");
label.setIcon(icon);
this.add(label);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
/**
* 刷新图片
*/
public void refreshImage(byte[] data) {
label.setIcon(new ImageIcon(data));
}
}
package com.it18zhang.udp.screenbroadcast;
import java.io.ByteArrayOutputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipOutputStream;
/**
* 数据工具类
*/
public class DataUtil {
/**
* 使用zip算法进行压缩处理
*/
public static byte[] zipCompress(byte[] data) {
try {
//压缩过程
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
zos.write(data);
zos.close();
return baos.toByteArray();
}
catch (Exception e) {
e.printStackTrace();
}
return null ;
}
/**
* 使用gzip算法进行压缩处理
*/
public static byte[] gzipCompress(byte[] data) {
try {
//压缩过程
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzos = new GZIPOutputStream(baos);
gzos.write(data);
return baos.toByteArray();
}
catch (Exception e) {
e.printStackTrace();
}
return null ;
}
/**
* 将long型数据转换成8个字节
*/
public static byte[] long2Bytes(long l) {
byte[] bytes = new byte[8] ;
bytes[0] = (byte)(l >> 56 );
bytes[1] = (byte)(l >> 48 );
bytes[2] = (byte)(l >> 40 );
bytes[3] = (byte)(l >> 32 );
bytes[4] = (byte)(l >> 24 );
bytes[5] = (byte)(l >> 16 );
bytes[6] = (byte)(l >> 8 );
bytes[7] = (byte)(l >> 0 );
return bytes ;
}
/**
* 将long型数据转换成8个字节
*/
public static long bytes2Long(byte[] bytes) {
long l0 = (bytes[0] & 0xffL) << 56 ;
long l1 = (bytes[1] & 0xffL) << 48 ;
long l2 = (bytes[2] & 0xffL) << 40 ;
long l3 = (bytes[3] & 0xffL) << 32 ;
long l4 = (bytes[4] & 0xffL) << 24 ;
long l5 = (bytes[5] & 0xffL) << 16 ;
long l6 = (bytes[6] & 0xffL) << 8 ;
long l7 = (bytes[7] & 0xffL) << 0 ;
return l0 | l1 | l2 | l3 | l4 | l5 | l6 | l7 ;
}
}
package com.it18zhang.udp.screenbroadcast;
import java.net.DatagramPacket;
/**
* 一帧画面的每个单元 PackProtocal
*/
public class FrameUnit {
// 组id,时间戳
private long gid;
// 包数量
private int count;
// 包序号
private int index;
// 原始数据
private byte[] rawData;
// 构造
public FrameUnit(DatagramPacket pack) {
parsePack(pack);
}
/**
* 解析包结构
*/
private void parsePack(DatagramPacket pack) {
//
byte[] buf = pack.getData();
int length = pack.getLength();
// 处理有效数据
byte[] validData = new byte[length];
System.arraycopy(buf, 0, validData, 0, length);
// gid
this.gid = DataUtil.bytes2Long(validData);
this.count = validData[8];
this.index = validData[9];
// 有效数据
rawData = new byte[length - 10];
System.arraycopy(validData, 10, rawData, 0, length - 10);
}
public long getGid() {
return gid;
}
public void setGid(long gid) {
this.gid = gid;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public byte[] getRawData() {
return rawData;
}
public void setRawData(byte[] rawData) {
this.rawData = rawData;
}
}
package com.it18zhang.udp.screenbroadcast;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.p_w_picpath.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import javax.p_w_picpathio.ImageIO;
/**
* 服务器发送
*/
public class ScreenBrocastCastServer {
public static void main(String[] args) throws Exception {
//
DatagramSocket sock = new DatagramSocket(8888);
while(true){
//抓图
byte[] raw = captureScreen();
//创建数据包组
List<DatagramPacket> packs = splitPack(raw,InetAddress.getByName("192.168.12.255") ,8889);
for(DatagramPacket p : packs){
sock.send(p);
}
}
}
/**
* 抓屏
*/
public static byte[] captureScreen(){
try {
//创建屏幕的抓图区域
Rectangle rect = new Rectangle(0, 0, 1024, 768);
BufferedImage p_w_picpath = new Robot().createScreenCapture(rect);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(p_w_picpath, "jpg", baos);
byte[] rawData = baos.toByteArray();
return rawData ;
}
catch (Exception e) {
e.printStackTrace();
}
return null ;
}
/**
* 切割原始报文,生成n个pack对象
*/
public static List<DatagramPacket> splitPack(byte[] rawData,InetAddress addr ,int port){
//总长度
int allLen = rawData.length ;
//每个pack的长度
int lenPerPack = 50 * 1024 ;
//pack的个数
int count = 0 ;
if(allLen % lenPerPack == 0 ){
count = allLen / lenPerPack ;
}
else{
count = allLen / lenPerPack + 1;
}
//构造小包集合
//组id
long gid = System.nanoTime();
List<DatagramPacket> packs = new ArrayList<DatagramPacket>();
DatagramPacket pack = null ;
for(int i = 0 ; i < count ; i ++){
//
byte[] newPack = null ;
//是否是最后一个包
if(i != (count - 1)){
//8个字节:时间戳,
//1个字节:包数量 == count
//1个字节:小包的序号==i
newPack = new byte[lenPerPack + 10];
//处理gid
System.arraycopy(DataUtil.long2Bytes(gid), 0, newPack, 0, 8);
//小包数量
newPack[8] = (byte)count ;
//小包序号
newPack[9] = (byte)i ;
//抓图数据
System.arraycopy(rawData, i * lenPerPack, newPack, 10, lenPerPack);
}
//最后一个包
else{
//8个字节:时间戳,
//1个字节:包数量 == count
//1个字节:小包的序号==i
int remain = rawData.length - (count - 1) * lenPerPack ;//剩余长度
newPack = new byte[remain + 10];
//处理gid
System.arraycopy(DataUtil.long2Bytes(gid), 0, newPack, 0, 8);
//小包数量
newPack[8] = (byte)count ;
//小包序号
newPack[9] = (byte)i ;
//抓图数据
System.arraycopy(rawData, i * lenPerPack, newPack, 10, remain);
}
//创建pack
pack = new DatagramPacket(newPack, newPack.length,addr,port);
//添加到集合中
packs.add(pack);
}
return packs ;
}
}
package com.it18zhang.udp.screenbroadcast;
public class StartClient {
public static void main(String[] args) {
ClientUI ui = new ClientUI();
new ClientReceiverThread(ui).start();
}
}
package com.it18zhang.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Receiver {
public static void main(String[] args) throws Exception {
DatagramSocket sock = new DatagramSocket(8889);
while(true){
byte[] buf = new byte[1024];
DatagramPacket pack = new DatagramPacket(buf, 1024);
sock.receive(pack);
//获取接收到的消息长度
int len = pack.getLength();
System.out.println(new String(buf,0,len));
Thread.sleep(500);
}
}
}
package com.it18zhang.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* UDP发送器
*/
public class Sender {
public static void main(String[] args) throws Exception {
//8888是数据包套接字端口号,使用该端口向外发送
DatagramSocket sock = new DatagramSocket(8888);
int i = 1 ;
while(true){
//构造数据包套接字对象
//创建缓冲区
byte[] buf = null ;//("helloworld - " + i).getBytes();
buf = new byte[1024 * 60];
//构造数据报包
DatagramPacket pack = new DatagramPacket(buf, buf.length);
//构造发送的地址+port,
//192.168.12.255 ->通配地址,该网段内的所有主机。
InetAddress addr = InetAddress.getByName("192.168.12.255");
pack.setAddress(addr);
pack.setPort(8889);
//通过sock方法数据报包
sock.send(pack);
//编号
i ++ ;
}
}
}
package com.it18zhang.udp;
import com.it18zhang.udp.screenbroadcast.ScreenBrocastCastServer;
public class TestApp {
public static void main(String[] args) {
long l = System.currentTimeMillis();
System.out.println(l);
}
}
转载于:https://blog.51cto.com/it18zhang/1754008
IT十八掌作业_java基础第十八天_项目完善相关推荐
- IT十八掌作业_java基础第十二天_集合
1.描述HashMap内部实现原理. 2.描述Hashset和HashMap的区别. 3.年级的集合使用Map的嵌套实现. 10班,每个班50人. 4.编程实现文本文件的复制.合理设计程序,得到缓冲区 ...
- IT十八掌作业_java基础第二天_进制转换原理和补码存储方式
1:负数的表现形式,为什么如此设计? 答:负数在内存中是以补码的形式存储的,补码时在原码的基础上取反加一 得到的.负数在内存中这样设计是为了互为相反数的两个数相加能够得到0的结 果. 2:-128在内 ...
- IT十八掌作业_java基础第八天_多线程
/** *1. 5辆汽车过山洞,依次经过山洞.每辆车通过山洞花费10秒,使用多线程实现. */ //山洞 class Cave { } //汽车 class Car extends Thread { ...
- IT十八掌作业_java基础第六天_接口与适配器模式、多态、内部类
[作业1] ------------------------------------ 使用抽象类和接口实现适配器模式设计.涉及的类和接口分别为ButtonListener(接口), 其中含有click ...
- IT十八掌作业_java基础第十一天_集合
1.定义罪犯Criminal类,height(身高)/weight(体重)/blood(血型)/home(籍贯)属性. 重写hashcode和equals,使用四个属性的组合进行实现. 创建HashS ...
- IT十八掌作业_java基础第十六天_GUI/socket
参照视频,编写出聊天程序. 知识点分析: Socket + GUI + IO = 简版QQ ------------------------------ 1.GUI 2.Socket Server ...
- 【十八掌●内功篇】第五掌:HDFS之基础知识
这一篇博文是[大数据技术●降龙十八掌]系列文章的其中一篇,点击查看目录:大数据技术●降龙十八掌 系列文章: [十八掌●内功篇]第五掌:HDFS之基础知识 [十八掌●内功篇]第五掌:HDFS之Shell ...
- Java从键盘输入n行字符串_Java十四天零基础入门-Java布尔类型
不闲聊!!!不扯淡!!!小UP只分享Java相关的资源干货 Java布尔类型 在Java语言中布尔类型的值只包括true和false,没有其他值,不包括1和0,布尔类型的数据在开发中主要使用在逻辑判断 ...
- java短除法获取二进制_Java十四天零基础入门-Java的数据类型介绍
不闲聊!!!不扯淡!!!小UP只分享Java相关的资源干货 本章节目标: 理解数据类型的作用.Java中包括哪些数据类型?常见的八种基本数据类型都有哪些?会用八种基本数据类型声明变量?什么是二进制?原 ...
最新文章
- Linux中grep命令 常用选项
- 【Python】from __future__ import absolute_import的作用
- PE文件格式详解(二)
- 30余种加密编码类型的密文特征分析
- Nginx学习笔记(二) Nginx--connectionrequest
- mongo 监听指定语句
- 双线性的定义以及他的性质
- 【iphone4s/ipad2回滚ios6.1.3】file:installer.cpp; line: 71; what:_assert(teams.empty()) 报错解决方法
- 高德地图通过经纬度定位并打上标记
- 图片实现裁剪功能vue-img-cutter
- “HEAP:Invalid Address specified to RtlValidateHeap( 000D0000, 019FEF18 )错误
- ubuntu22 使用todesk被远程控制时显示黑屏或者白屏
- Core Animation学习笔记—第二节Setting up Layer Objects
- Ubuntu 4.10 (Warty Warthog,长疣的疣猪)
- STM32:使用ST官方的原理图和PCB封装
- w7运行里的计算机怎么设置,W7系统怎么设置开机启动项
- 《炬丰科技-半导体工艺》单层胶体晶体的微纳米光刻技术研究进展
- linux 安装字体 注册表,如何安装字体,如何安装字体?
- PowerDesigner16.5破解版安装
- iview DatePicker 结束时间改为23:59:59