From 05e5da7edd1368a2e8f216b3efc6e87eb8d375a2 Mon Sep 17 00:00:00 2001 From: ‘liusuyi’ <1951119284@qq.com> Date: 星期一, 26 六月 2023 17:24:58 +0800 Subject: [PATCH] 解析雷达报警报文 --- src/main/java/com/ard/utils/tcp/NettyTcpClient.java | 9 + src/main/java/com/ard/utils/tcp/index.java | 33 ++++ src/main/java/com/ard/utils/SpringTool.java | 17 ++ src/main/resources/logback-spring.xml | 26 +++ src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java | 324 ++++++++++++++++++++++++++++++++++++++++++++- src/main/java/com/ard/alarm/tube/service/TubeAlarmService.java | 6 6 files changed, 402 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/ard/alarm/tube/service/TubeAlarmService.java b/src/main/java/com/ard/alarm/tube/service/TubeAlarmService.java index 360f727..3106e6a 100644 --- a/src/main/java/com/ard/alarm/tube/service/TubeAlarmService.java +++ b/src/main/java/com/ard/alarm/tube/service/TubeAlarmService.java @@ -42,9 +42,9 @@ return; } nettyUdpServer.init(udpPort); - log.info("UDP鏈嶅姟宸茬粡鍚姩"); - nettyTcpClient.init("112.98.126.2",1200); - log.info("TCP瀹㈡埛绔凡杩炴帴"); + log.info("UDP鏈嶅姟宸插惎鍔�"); + nettyTcpClient.init("127.0.0.1",1200); + log.info("TCP瀹㈡埛绔凡鍚姩"); } @Async("alarm") diff --git a/src/main/java/com/ard/utils/SpringTool.java b/src/main/java/com/ard/utils/SpringTool.java index 2aff71c..e152dde 100644 --- a/src/main/java/com/ard/utils/SpringTool.java +++ b/src/main/java/com/ard/utils/SpringTool.java @@ -32,4 +32,21 @@ public static Object getBean(String name) { return getApplicationContext().getBean(name); } + + /** + * Byte瀛楄妭杞琀ex + * @param b 瀛楄妭 + * @return Hex + */ + public static String byteToHex(byte b) + { + String hexString = Integer.toHexString(b & 0xFF); + //鐢变簬鍗佸叚杩涘埗鏄敱0~9銆丄~F鏉ヨ〃绀�1~16锛屾墍浠ュ鏋淏yte杞崲鎴怘ex鍚庡鏋滄槸<16,灏变細鏄竴涓瓧绗︼紙姣斿A=10锛夛紝閫氬父鏄娇鐢ㄤ袱涓瓧绗︽潵琛ㄧず16杩涘埗浣嶇殑, + //鍋囧涓�涓瓧绗︾殑璇濓紝閬囧埌瀛楃涓�11锛岃繖鍒板簳鏄�1涓瓧鑺傦紝杩樻槸1鍜�1涓や釜瀛楄妭锛屽鏄撴贩娣嗭紝濡傛灉鏄ˉ0锛岄偅涔�1鍜�1琛ュ厖鍚庡氨鏄�0101锛�11灏辫〃绀虹函绮圭殑11 + if (hexString.length() < 2) + { + hexString = new StringBuilder(String.valueOf(0)).append(hexString).toString(); + } + return hexString.toUpperCase(); + } } \ No newline at end of file diff --git a/src/main/java/com/ard/utils/tcp/NettyTcpClient.java b/src/main/java/com/ard/utils/tcp/NettyTcpClient.java index 2d01793..2d6c324 100644 --- a/src/main/java/com/ard/utils/tcp/NettyTcpClient.java +++ b/src/main/java/com/ard/utils/tcp/NettyTcpClient.java @@ -2,6 +2,7 @@ import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelInitializer; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; @@ -36,6 +37,14 @@ } }); ChannelFuture future = bootstrap.connect(host, port).sync(); + // 娣诲姞杩炴帴鎴愬姛鐨勭洃鍚櫒 + future.addListener((ChannelFutureListener) future1 -> { + if (future1.isSuccess()) { + log.info("tcp杩炴帴鎴愬姛"+host+":"+port); + } else { + log.info("tcp杩炴帴澶辫触"+host+":"+port); + } + }); future.channel().closeFuture().sync(); } catch (Exception ex) { diff --git a/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java b/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java index 5770cdc..626aff8 100644 --- a/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java +++ b/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java @@ -1,11 +1,17 @@ package com.ard.utils.tcp; +import com.ard.utils.SpringTool; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import lombok.extern.slf4j.Slf4j; +import sun.nio.cs.ext.GBK; import javax.xml.bind.DatatypeConverter; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.*; /** * @Description: tcp瀹㈡埛绔鐞� @@ -14,30 +20,328 @@ * @Date: 2023骞�06鏈�25鏃�17:02 * @Version: 1.0 **/ -@Slf4j +@Slf4j(topic = "radar") public class NettyTcpClientHandler extends SimpleChannelInboundHandler<ByteBuf> { + @Override - protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg){ + protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) { // 澶勭悊鎺ユ敹鍒扮殑娑堟伅 byte[] byteArray = new byte[msg.readableBytes()]; msg.getBytes(msg.readerIndex(), byteArray); - String hexString = DatatypeConverter.printHexBinary(byteArray); - - log.info("Received: " + hexString); + byte[] bytes = receiveCompletePacket(byteArray); + if (bytes != null) { + String hexString = DatatypeConverter.printHexBinary(bytes); + log.info(hexString); + processData(bytes); + } } @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { + public void channelActive(ChannelHandlerContext ctx) { // 褰撳鎴风杩炴帴鎴愬姛鍚庯紝鍙戦�佹秷鎭粰鏈嶅姟鍣� - ByteBuf message = ctx.alloc().buffer(); - message.writeBytes("Hello, Server!".getBytes()); - ctx.writeAndFlush(message); + TimerTask timerTask = new TimerTask() { + @Override + public void run() { + ByteBuf message = ctx.alloc().buffer(); + byte[] heart = {0x01, 0x02, 0x01, 0x10, 0x00, 0x00, 0x00, (byte) 0x83, (byte) 0x88, 0x5d, 0x71, 0x01, 0x02, 0x00}; + String hexString = DatatypeConverter.printHexBinary(heart); + log.info("鍙戦�佸績璺�:" + hexString); + message.writeBytes(heart); + ctx.writeAndFlush(message); + } + }; + Timer timer = new Timer(); + // timer.schedule(timerTask, 0, 6000); } @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){ + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + log.error("杩炴帴寮傚父"); // 鍙戠敓寮傚父鏃剁殑澶勭悊 cause.printStackTrace(); ctx.close(); } + + public static void processData(byte[] data) { + try { + data = transferData(data);//鍘绘帀鍖呭ご鍜屽寘灏惧強杞箟 + String s = DatatypeConverter.printHexBinary(data); + log.info(s); + byte[] type = Arrays.copyOfRange(data, index.type[0], index.type[1]);//鍛戒护绫诲瀷 + log.info("鍛戒护绫诲瀷:" + DatatypeConverter.printHexBinary(type)); + + byte[] cmdId = Arrays.copyOfRange(data, index.funcc[0], index.funcc[1]);//鍛戒护ID + log.info("鍛戒护ID:" + DatatypeConverter.printHexBinary(cmdId)); + + byte[] payloadSize = Arrays.copyOfRange(data, index.payloadSize[0], index.payloadSize[1]);//鏈夋晥璐熻浇澶у皬 + // log.info("鏈夋晥璐熻浇澶у皬:" + DatatypeConverter.printHexBinary(payloadSize)); + payloadSize = toLittleEndian(payloadSize); + // log.info("鏈夋晥璐熻浇澶у皬(杞皬绔�):" + DatatypeConverter.printHexBinary(payloadSize)); + int payloadSizeToDecimal = byteArrayToDecimal(payloadSize); + log.info("鏈夋晥璐熻浇澶у皬(杞暣鍨�):" + payloadSizeToDecimal); + + if (Arrays.equals(cmdId, new byte[]{0x01})) { + byte[] dwTim = Arrays.copyOfRange(data, index.dwTim[0], index.dwTim[1]); + // log.info("鍛ㄨ鍥惧儚鐨勫嚭鐜版椂闂�:" + DatatypeConverter.printHexBinary(dwTim)); + dwTim = toLittleEndian(dwTim); + // log.info("鍛ㄨ鍥惧儚鐨勫嚭鐜版椂闂�(杞皬绔�):" + DatatypeConverter.printHexBinary(dwTim)); + // log.info("鍛ㄨ鍥惧儚鐨勫嚭鐜版椂闂�(杞暣鍨�):" + byteArrayToDecimal(dwTim)); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + long l = byteArrayToDecimal(dwTim); + String format = sdf.format(l * 1000); + log.info("鍛ㄨ鍥惧儚鐨勫嚭鐜版椂闂�(杞琩ate):" + format); + + byte[] wTargetNum = Arrays.copyOfRange(data, index.wTargetNum[0], index.wTargetNum[1]); + wTargetNum = toLittleEndian(wTargetNum); + // log.info("鐩爣鎬荤偣鏁�(杞皬绔�):" + DatatypeConverter.printHexBinary(wTargetNum)); + int targetNum = byteArrayToDecimal(wTargetNum); + log.info("鐩爣鎬荤偣鏁�(杞暣鍨�):" + targetNum); + + //瑙f瀽NET_TARGET_UNIT(64鏄疦ET_TARGET_HEAD鐨勫瓧鑺傛暟) + int unitIndex = index.acRes[1]; + log.info("鏈夋晥璐熻浇鏃犲ご璧峰浣�:" + unitIndex); + +// byte datum = data[unitIndex]; +// log.info("鏃犲ご璧峰瀛楄妭锛�" + SpringTool.byteToHex(datum)); + int UNITNum = (payloadSizeToDecimal - 64) / targetNum; + log.info("鍗曚釜Unit澶у皬:" + UNITNum); + for (int i = 0; i < targetNum; i++) { + Integer index = unitIndex + UNITNum * i; + byte[] dwID = Arrays.copyOfRange(data, index, index + 4); + dwID = toLittleEndian(dwID); + // log.info("dwID锛�" + DatatypeConverter.printHexBinary(dwID)); + int id = byteArrayToDecimal(dwID); + log.info("鐩爣ID鍙凤細" + id); + + byte[] dwGSum = Arrays.copyOfRange(data, index + 4, index + 8); + dwGSum = toLittleEndian(dwGSum); + int GSum = byteArrayToDecimal(dwGSum); + log.info("鐩爣褰撳墠鍍忕礌鐏板害鍜岋細" + GSum); + + byte[] iDistance = Arrays.copyOfRange(data, index + 8, index + 12); + iDistance = toLittleEndian(iDistance); + int Distance = byteArrayToDecimal(iDistance); + log.info("鐩爣褰撳墠璺濈(m):" + Distance); + + byte[] iTw = Arrays.copyOfRange(data, index + 12, index + 16); + iTw = toLittleEndian(iTw); + int Tw = byteArrayToDecimal(iTw); + log.info("鐩爣褰撳墠鐨勫儚绱犲搴�:" + Tw); + + byte[] iTh = Arrays.copyOfRange(data, index + 16, index + 20); + iTh = toLittleEndian(iTh); + int Th = byteArrayToDecimal(iTh); + log.info("鐩爣褰撳墠鐨勫儚绱犻珮搴�:" + Th); + + byte[] wPxlArea = Arrays.copyOfRange(data, index + 20, index + 22); + wPxlArea = toLittleEndian(wPxlArea); + int PxlArea = byteArrayToDecimal(wPxlArea); + log.info("鐩爣褰撳墠鍍忕礌闈㈢Н:" + PxlArea); + + byte[] cTrkNum = Arrays.copyOfRange(data, index + 22, index + 23); + cTrkNum = toLittleEndian(cTrkNum); + int TrkNum = byteArrayToDecimal(cTrkNum); + log.info("杞ㄨ抗鐐规暟:" + TrkNum); + + byte[] cStat = Arrays.copyOfRange(data, index + 23, index + 24); + cStat = toLittleEndian(cStat); + int Stat = byteArrayToDecimal(cStat); + log.info("鐩爣褰撳墠鐘舵��:" + Stat); + + byte[] sVx = Arrays.copyOfRange(data, index + 24, index + 26); + sVx = toLittleEndian(sVx); + int Vx = byteArrayToDecimal(sVx); + log.info("鐩爣褰撳墠閫熷害鐭㈤噺(鍍忕礌璺濈)X:" + Vx); + + byte[] sVy = Arrays.copyOfRange(data, index + 26, index + 28); + sVy = toLittleEndian(sVy); + int Vy = byteArrayToDecimal(sVy); + log.info("鐩爣褰撳墠閫熷害鐭㈤噺(鍍忕礌璺濈)Y:" + Vy); + + byte[] sAreaNo = Arrays.copyOfRange(data, index + 28, index + 30); + sAreaNo = toLittleEndian(sAreaNo); + int AreaNo = byteArrayToDecimal(sAreaNo); + log.info("鐩爣褰掑睘鐨勫憡璀﹀尯鍩熷彿:" + AreaNo); + + byte[] cGrp = Arrays.copyOfRange(data, index + 30, index + 31); + cGrp = toLittleEndian(cGrp); + int Grp = byteArrayToDecimal(cGrp); + log.info("鎵�灞炵粍:" + Grp); + + byte[] szName = Arrays.copyOfRange(data, index + 64, index + 96); + String str = new String(szName, "GBK"); + log.info("鎵�灞炲憡璀﹀尯鍩熷悕绉�:" + str); + } + } + } catch (Exception ex) { + log.error(ex.getMessage()); + } + } + + public static int byteArrayToDecimal(byte[] byteArray) { + int decimalValue = 0; + + for (int i = 0; i < byteArray.length; i++) { + decimalValue = (decimalValue << 8) | (byteArray[i] & 0xFF); + } + + return decimalValue; + } + + public static byte[] toLittleEndian(byte[] bigEndianBytes) { + byte[] littleEndianBytes = new byte[bigEndianBytes.length]; + + for (int i = 0; i < bigEndianBytes.length; i++) { + int j = bigEndianBytes.length - i - 1; + littleEndianBytes[i] = bigEndianBytes[j]; + } + + return littleEndianBytes; + } + + + public static Integer processPayloadSize(String payloadSize) {//瑙f瀽鏈夋晥璐熻浇澶у皬 + Integer payloadSizeInfo = 0; + String[] payloadSizeArr = payloadSize.split(""); + for (int i = 0; i <= payloadSizeArr.length - 1; i++) { + Integer num = null; + switch (payloadSizeArr[i]) { + case "0": + num = 0; + break; + case "1": + num = 1; + break; + case "2": + num = 2; + break; + case "3": + num = 3; + break; + case "4": + num = 4; + break; + case "5": + num = 5; + break; + case "6": + num = 6; + break; + case "7": + num = 7; + break; + case "8": + num = 8; + break; + case "9": + num = 9; + break; + case "a": + num = 10; + break; + case "b": + num = 11; + break; + case "c": + num = 12; + break; + case "d": + num = 13; + break; + case "e": + num = 14; + break; + case "f": + num = 15; + break; + default: + break; + } + if (i % 2 == 0) { + payloadSizeInfo = payloadSizeInfo + num * 16; + } else { + payloadSizeInfo = payloadSizeInfo + num * 256; + } + } + return payloadSizeInfo; + } + + public static Boolean checkPayloadSize(Integer payloadSizeInfo, String data) {//鏍¢獙鏈夋晥璐熻浇澶у皬 + Integer payloadSize = (data.length() - 8 - 8) / 2;//鍘婚櫎鍖呭ご8浣嶅拰鏍¢獙8浣� + if (payloadSize.equals(payloadSizeInfo)) { + return true; + } else { + return false; + } + } + + // 鍒涘缓缂撳啿鍖哄垪琛� + List<Byte> buffer = new ArrayList<>(); + + public byte[] receiveCompletePacket(byte[] receivedData) { + // 瀹氫箟鍖呭熬瀛楄妭搴忓垪 + byte[] packetEnd = {0x01, 0x02, 0x00}; + // 娣诲姞宸叉帴鏀剁殑鏁版嵁鍒扮紦鍐插尯 + for (byte data : receivedData) { + buffer.add(data); + } + // 妫�鏌ョ紦鍐插尯涓殑鏁版嵁鏄惁鍖呭惈瀹屾暣鐨勫寘 + while (buffer.size() >= packetEnd.length) { + int endIndex = findPacketEndIndex(buffer, packetEnd); + if (endIndex != -1) { + // 鎵惧埌瀹屾暣鐨勫寘 + byte[] packet = extractPacketFromBuffer(buffer, endIndex + packetEnd.length); + return packet; + } else { + // 鏈壘鍒板寘灏撅紝缁х画鎺ユ敹鏁版嵁 + break; + } + } + + // 鏈壘鍒板畬鏁寸殑鍖� + return null; + } + + public static int findPacketEndIndex(List<Byte> buffer, byte[] packetEnd) { + for (int i = 0; i <= buffer.size() - packetEnd.length; i++) { + boolean isMatch = true; + for (int j = 0; j < packetEnd.length; j++) { + if (buffer.get(i + j) != packetEnd[j]) { + isMatch = false; + break; + } + } + if (isMatch) { + return i; + } + } + return -1; + } + + public static byte[] extractPacketFromBuffer(List<Byte> buffer, int endIndex) { + byte[] packet = new byte[endIndex]; + for (int i = 0; i < endIndex; i++) { + packet[i] = buffer.get(i); + } + buffer.subList(0, endIndex).clear(); + return packet; + } + + //鍘绘帀鍖呭ご鍜屽寘灏炬牎楠屽強杞箟 + public static byte[] transferData(byte[] data) { + data = Arrays.copyOfRange(data, 3, data.length); + data = Arrays.copyOfRange(data, 0, data.length - 7); + String dataStr = DatatypeConverter.printHexBinary(data); + if (dataStr.contains("01020201")) {//杞箟01020201 + dataStr = dataStr.replaceAll("01020201", "010201"); + } + if (dataStr.contains("01020200")) {//杞箟01020200 + dataStr = dataStr.replaceAll("01020200", "010200"); + } + if (dataStr.contains("01020202")) {//杞箟01020202 + dataStr = dataStr.replaceAll("01020202", "010202"); + } + data = DatatypeConverter.parseHexBinary(dataStr); + return data; + } } diff --git a/src/main/java/com/ard/utils/tcp/index.java b/src/main/java/com/ard/utils/tcp/index.java new file mode 100644 index 0000000..c4ae70c --- /dev/null +++ b/src/main/java/com/ard/utils/tcp/index.java @@ -0,0 +1,33 @@ +package com.ard.utils.tcp; + +/** + * @Description: + * @ClassName: domain + * @Author: 鍒樿嫃涔� + * @Date: 2023骞�06鏈�26鏃�15:21 + * @Version: 1.0 + **/ +public class index { + //header + public static Integer[] type = {0,1}; + public static Integer[] funcc = {1,2}; + public static Integer[] payloadSize = {2,4}; + //NET_TARGET_HEAD + public static Integer[] dwTim = {4,8}; + public static Integer[] wTargetNum = {8,10}; + public static Integer[] acRes = {10,68}; + //NET_TARGET_UNIT +// public static Integer[] dwID = {68,72}; +// public static Integer[] dwGSum = {}; +// public static Integer[] iDistance = 2; +// public static Integer[] cTrkNum = 1; +// public static Integer[] cStat = 1; +// public static Integer[] sVx = 2; +// public static Integer[] sVy = 2; +// public static Integer[] sAreaNo = 2; +// public static Integer[] cGrp = 1; +// public static Integer[] acRes1 = 33; +// public static Integer[] szName = 32; +// public static Integer[] afTx = 16; +// public static Integer[] afTy = 16; +} diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index 7f2dac9..390b765 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -76,6 +76,28 @@ <onMismatch>DENY</onMismatch> </filter> </appender> + <!--闆疯揪鎶ヨ鏃ュ織杈撳嚭--> + <appender name="radar" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${log.path}/radar.log</file> + <!--寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠�--> + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> + <!--鏃ュ織鏂囦欢鍚嶆牸寮�--> + <fileNamePattern>${log.path}/radar.%d{yyyy-MM-dd}.log</fileNamePattern> + <!--鏃ュ織鏈�澶х殑鍘嗗彶60澶�--> + <maxHistory>60</maxHistory> + </rollingPolicy> + <encoder> + <pattern>${log.pattern}</pattern> + </encoder> + <filter class="ch.qos.logback.classic.filter.LevelFilter"> + <!--杩囨护鐨勭骇鍒�--> + <level>INFO</level> + <!--鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛�--> + <onMatch>ACCEPT</onMatch> + <!--涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛�--> + <onMismatch>DENY</onMismatch> + </filter> + </appender> <root level="DEBUG"> <appender-ref ref="console"/> </root> @@ -91,5 +113,9 @@ <root level="INFO"> <appender-ref ref="camera"/> </root> + <!--闆疯揪鎶ヨ鏃ュ織--> + <root level="INFO"> + <appender-ref ref="radar"/> + </root> </configuration> -- Gitblit v1.9.3