package com.jxkj.udp.server; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import com.jxkj.util.Util; /** * 接收UDP数据 * @author sourcezero * */ public class UdpServer { private static Logger logger = Logger.getLogger(UdpServer.class); private static int port = 9999; public static byte start_flag = (byte) 0x68; public static void main(String[] args) { DatagramSocket ds = null; try { if(args!=null&&args.length>0){ port = Integer.valueOf(args[0]); } logger.info("开始监听端口 " + port + " 的数据..."); InetAddress addr = InetAddress.getLocalHost(); InetSocketAddress socketAddress = new InetSocketAddress(port); ds = new DatagramSocket(socketAddress); logger.info("主机名:" + addr.getHostName() + ", ip地址:" + addr.getHostAddress()); //ds.setSoTimeout(600 * 1000); ds.setSoTimeout( 3000);//阻塞等待时长 while (true) { byte[] buffer = new byte[65*1024]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); try{ ds.receive(packet);// 17313 3072 logger.info("接收到来自ip:"+packet.getAddress()+",端口为"+packet.getPort()+"的数据"); byte[] data = packet.getData(); if(data.length>0){ List<byte[]> list = splitMessage(data); for (byte[] bs : list) { String content = Util.hexDecode(hex2String(toHexString(bs))); System.out.println(content); } } }catch(SocketTimeoutException ste){ //logger.error("接收UDP数据超时..."); }catch(Exception e){ logger.error("接收UDP出错...",e); } } } catch (IOException e) { logger.error(e); }finally{ if(ds!=null){ ds.close(); } } } public static String hex2String(String hex) { StringBuilder sb = new StringBuilder(); StringBuilder temp = new StringBuilder(); // 49204c6f7665204a617661 split into two characters 49, 20, 4c... for (int i = 0; i < hex.length() - 1; i += 2) { // grab the hex in pairs String output = hex.substring(i, (i + 2)); // convert hex to decimal int decimal = Integer.parseInt(output, 16); // convert the decimal to character sb.append((char) decimal); temp.append(decimal); } return sb.toString(); } public static String toHexString(byte[] buf) { String hex = ""; if (buf == null) return hex; for (int i = 0; i < buf.length; i++) { hex += toHexString(buf[i]); } return hex; } public static List<byte[]> splitMessage(byte[] message) { List<byte[]> list = new ArrayList<byte[]>(); int len = 0; for (int i = 0; i < message.length;) { // 以68为标识进行切分 if (message[i] == start_flag) { // 发送站端地址 logger.debug("发送站端地址:" + asUnsignedByte(message[1])); // 报文长度 len = valueOf2byte(message[i + 2],message[i + 3]); logger.debug("报文长度:"+len); if (len > 0) { byte[] submessage = new byte[len]; for (int k = 0; k < len; k++) { int tmp =11+k; submessage[k] = message[tmp]; } list.add(submessage); // 校验码为unsigned short类型,生成方式为从启动字符开始至报文体结束的unsigned char // 的算术累加和,进位位丢弃。 // log.debug("校验码:"+ByteUtil.bytesToShort(message,len+4)); i += len + 11; } } i++; } return list; } /** * @param hight 高位 * @param low 低位 * @return int */ public static int valueOf2byte(byte low, byte hight) { String value = toHexString(low) + toHexString(hight); return Integer.parseInt(value, 16); } public static int asUnsignedByte(byte b) { return Integer.parseInt(toHexString(b), 16); } /** * 将字节转换为用16进表示的字符串 * * @param buf * byte * @return String */ public static String toHexString(byte b) { String s = Integer.toHexString(b); if (s.length() == 1) { s = "0" + s; } else if (s.length() > 2) { s = s.substring(s.length() - 2); } return s; } public static byte[] addBytes(byte[] data1, byte[] data2) { byte[] data3 = new byte[data1.length + data2.length]; System.arraycopy(data1, 0, data3, 0, data1.length); System.arraycopy(data2, 0, data3, data1.length, data2.length); return data3; } }