Java自定义协议报文封装 添加Crc32校验的实例

您所在的位置:网站首页 socket封装库 Java自定义协议报文封装 添加Crc32校验的实例

Java自定义协议报文封装 添加Crc32校验的实例

2023-03-11 14:12| 来源: 网络整理| 查看: 265

 当前位置:首页 » 编程设计 » 正文 Java自定义协议报文封装 添加Crc32校验的实例 2023年03月07日6tintown

刚做完的demo,直接进入主题了,开启两个线程,模拟Socket服务端和客户端通信,将数据封装为指定格式报文发送

代码:

import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; /** * Created by SiKang on 2016/4/29. */ public class CustomData { public static void main(String args[]) { //服务端线程 new Thread(new Runnable() { @Override public void run() { try { //开启服务端Socket ServerSocket server = new ServerSocket(9000); //等待客户端连接 Socket socket = server.accept(); InputStream inputStream = socket.getInputStream(); //先得到前两个字节 为报文长度 byte[] lenBytes = new byte[2]; inputStream.read(lenBytes); short length = bytesToShort(lenBytes); System.out.println("length: " + length); //然后得到接下来的四个字节 crc32校验码 byte[] crc = new byte[4]; inputStream.read(crc); int crc32 = bytesToInt(crc); //得到剩下的字段 ver、cmd、data byte[] bytes = new byte[length - 2 - 4]; inputStream.read(bytes); //根据得到的bytes获取新的Crc32校验码 验证数据是否完整(可以在读取bytes时少读一位,看看能不能通过) if (crc32 == getCRC32(bytes)) { System.out.println("Crc32 Right!"); }else{ System.out.println("Crc32 Error!"); return; } //取出ver cmd int ver = Integer.parseInt(byteToHex(bytes[0]), 16); int cmd = Integer.parseInt(byteToHex(bytes[1]), 16); //看看ver是否是客户端发送0x05 if (ver == 0x05) { System.out.println("ver: 0x05"); } //cmd是否是客户端发送0xff if (cmd == 0xff) { System.out.println("cmd: 0xff"); } //得到剩下的数据字节数,取出data数据 int datalen = length - 2 - 4 - 1 - 1; byte[] data = new byte[datalen]; int index = 1; for (int i = 0; i < datalen; i++) { data[i] = bytes[++index]; } String str = new String(data); System.out.println("data: " + str); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }).start(); //客户端线程 new Thread(new Runnable() { @Override public void run() { try { //连接服务端 Socket socket = new Socket(getIpAddress(), 9000); OutputStream outputStream = socket.getOutputStream(); String str = "Hellow World!"; byte[] data = str.getBytes(); //发送报文 pack(outputStream, (byte) 0xff, data, data.length); outputStream.flush(); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }).start(); } /** *封装并发送报文 *这里报文格式为{报文总长度[2字节],Crc32校验码[4字节],ver版本信息[1字节],cmd指令[1字节],data数据内容[若干字节]} */ private static void pack(OutputStream out, byte cmd, byte[] data, int len) { try { //先得到报文总长度,如上介绍的格式 字节数相加 short totalSize = (short) (2 + 4 + 1 + 1 + len); //输出报文长度 out.write(shortToByte(totalSize), 0, 2); //需要校验的字段 byte[] bytes = new byte[1 + 1 + len]; int index = 0; bytes[index++] = 0x05;//版本号(这里是写死的) bytes[index++] = cmd;//cmd指令 //数据内容 for (int i = 0; i < len; i++) { bytes[index++] = data[i]; } //得到ver、cmd、data的crc32校验码(Crc32算法在最下边,网上找的.....) byte[] crc32 = intToBytes(getCRC32(bytes)); //输出crc校验码 out.write(crc32, 0, crc32.length); //输出ver、cmd、data out.write(bytes, 0, bytes.length); } catch (IOException e) { e.printStackTrace(); } } /** * 得到本机IP */ private static String getIpAddress() throws UnknownHostException { InetAddress address = InetAddress.getLocalHost(); return address.getHostAddress(); } /** * int转byte[] */ public static byte[] intToBytes(int value) { byte[] bytes = new byte[4]; bytes[3] = (byte) (value >> 24); bytes[2] = (byte) (value >> 16); bytes[1] = (byte) (value >> 8); bytes[0] = (byte) (value >> 0); return bytes; } /** * short转byte[] */ public static byte[] shortToByte(short value) { byte[] bytes = new byte[2]; bytes[1] = (byte) (value >> 8); bytes[0] = (byte) (value >> 0); return bytes; } /** * byte转16进制 */ public static String byteToHex(byte b) { int i = b & 0xFF; return Integer.toHexString(i); } /** * byte[]转int */ public static int bytesToInt(byte[] bytes) { return (int) ((((bytes[3] & 0xff)

上一篇: java中的interface接口实例详解

下一篇: Java内存大家都知道,但你知道要怎么管理Java内存吗

java   文章来源:ITGUEST,欢迎分享,转载请保留出处  原文地址:https://www.itguest.com/post/bcijf2b2.html 阅读延展 Java高并发编程AtomicReferenceJava 中怎么引入内存模型Java虚拟机中栈帧指的是什么线上FullGC频繁的排查怎么使用Java visualVM监控远程JVMJava中的String类Java项目中如何实现动态与静态编译如何使用HttpClient发送java对象到服务器Java 抽象类与接口的对比Java如何使用BIO和NIO进行文件操作对比JDK1.8的新特性有什么java如何去除图片中的白色背景


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3