package com.parna.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mysql.fabric.xmlrpc.base.Array;
import com.parna.cache.MeasurementCache;
import com.parna.cache.ServerConnCache;
import com.parna.cache.TestCache;
import com.parna.model.ServerInfoModel;
import com.parna.model.vo.AutoSaveModelVo;
import com.parna.model.vo.EditModel;
import com.parna.model.vo.EditSaveModelVo;
import com.parna.model.vo.GeneradeModel;
import com.parna.model.vo.MeasurementModelVo;
import com.parna.model.vo.RowModel;

/**
 * UDP数据转换辅助类
 * 
 * @author wude
 *
 */
public class UDPUtil {
    private  static Logger logger=LoggerFactory.getLogger(UDPUtil.class);
	private  static int port = 8080;
	public   static boolean riskctrlSwith=true;

	/**
	 * 字节数据转为十六进制字符串,中间用空格隔开
	 * 
	 * @param packet
	 * @return
	 */
	public static String receivePrint(DatagramPacket packet) {
		byte[] data = packet.getData();
		String printString = "";
		if (data != null || data.length > 0) {
			for (int i = 0; i < data.length; i++) {
				int v = data[i] & 0xFF;
				String hv = Integer.toHexString(v);
				if (hv.length() < 2) {
					printString += "0";
				}
				printString += hv + " "; // 补一个空格
			}
		}
		printString = printString.substring(0, packet.getLength() * 3).toUpperCase();
		return printString;
	}

	/**
	 * 十六进制字符串转为字节数组 格式07D0
	 * 
	 * @param cmdContent
	 * @return
	 */
	public static byte[] getstringToByte(String cmdContent) {
		String str = "0123456789ABCDEF";
		char[] hexs = cmdContent.toUpperCase().toCharArray();
		byte[] bytes = new byte[cmdContent.length() / 2];
		int n;
		for (int i = 0; i < bytes.length; i++) {
			n = str.indexOf(hexs[2 * i]) * 16;
			n += str.indexOf(hexs[2 * i + 1]);
			bytes[i] = (byte) (n & 0xff);
		}
		return bytes;
	}

	/**
	 * 字节数组转为String格式输出
	 * 
	 * @param bytes
	 * @return
	 */
	public static String getByteToString(byte[] bytes) {
		String a = "";
		for (int i = 0; i < bytes.length; i++) {
			int v = bytes[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				a += "0";
			}
			a += hv + " "; // 补一个空格
		}
		return a.toUpperCase();
	}
    
	/**
	 * 发送消息
	 * @param longhostIp  远程IP
	 * @param longPort    远程端口
	 * @param models      HashMap用于返回提示到前端
	 * @param b           消息字节数组
	 * @return    返回响应和对应提示
	 */
	public static Map<String, String> send(String longhostIp, int longPort, Map<String, String> models, byte[] b) {
		Date afterDate = null;
		DatagramSocket receiveSocket = null;
		DatagramPacket packet = null;
		Thread sendThread = null;
		int count=0;  //计数    发送失败后,再发两次
		boolean flag=true;
		try {
			packet = new DatagramPacket(b, b.length);
			
			if(ServerConnCache.getReceiveSocket("receiveSocket")==null){   //说明第一次使用
					receiveSocket = new DatagramSocket(8080,
						InetAddress.getByName(InetAddress.getLocalHost().getHostAddress()));
				ServerConnCache.setReceiveSocket("receiveSocket", receiveSocket);
			}else{
				receiveSocket=ServerConnCache.getReceiveSocket("receiveSocket");
			}
			ReceiveSocket sendRun = new ReceiveSocket(receiveSocket);
			sendThread = new Thread(sendRun);
			sendThread.start();
			// 接收数据清空
			ReceiveSocket.printString = null;
			// 发送器代码
			packet = new DatagramPacket(b, b.length, InetAddress.getByName(longhostIp), longPort);
		    while (flag==true) {
		    		if(ServerConnCache.getReceiveSocket("receiveSocket")!=null){
		    			System.out.println("==================================");
		    	    	System.out.println("【Send from "+InetAddress.getLocalHost().getHostAddress()+":"+8080+"】:"+UDPUtil.getByteToString(b));
		    	    	
						receiveSocket.send(packet);
		    	    }
					Date startTime = new Date();
				     do {
						afterDate = new Date(startTime.getTime() + 500);
					} while (System.currentTimeMillis() < afterDate.getTime());
				     
					if(ReceiveSocket.printString==null){ //发送失败
						flag=true;
						count++;
						if(count==3){
							flag=false; 
						}
					}else{
						if(!UDPUtil.getByteToString(b).substring(3, 5).equals(ReceiveSocket.printString.subSequence(3, 5))){
							count++;
							flag=true;   //重发
							System.out.println("重发。。。。。。。。");
							if(count==3){
								flag=false; 
							}
						}else{
							flag=false;   //成功
						}
						
					}
					System.out.println("【Receive from " + packet.getAddress().getHostAddress() + " :" + packet.getPort() + "】: "
							+ ReceiveSocket.printString);
					System.out.println("==================================");
		   }
		    sendThread.stop();
		} catch (IOException e) {
			logger.info("UDP发送接口出现问题:"+e.getMessage());
			e.printStackTrace();
			if(sendThread!=null){
				sendThread.stop();
			}
			models.put("desc", "指令失败!!"+e.getMessage());
			models.put("state", "N");
			return models;
		}
		models.put("desc", "指令成功!");
		models.put("state", "Y");
		models.put("data", ReceiveSocket.printString);
		return models;
	}

	/**
	 * 根据端口号获取对应的进程
	 * 
	 * @param port
	 * @return
	 */
	public static String getPID(String port) {
		InputStream is = null;
		BufferedReader br = null;
		String pid = null;
		String str=null;
		try {
			String[] args = new String[] { "cmd.exe", "/c", "netstat -aon|findstr", port };
			is = Runtime.getRuntime().exec(args).getInputStream();
			br = new BufferedReader(new InputStreamReader(is));
			String line = null;
			while ((line =br.readLine()) != null) {
				str=br.readLine();
			}
			if(str!=null){
				if(str.indexOf("UDP")==-1){  //  未已创建UDP协议					
					str=null;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
		
			try { br.close(); } catch (IOException e) { e.printStackTrace();
			 }
			 
		}
		return str;
	}

	/**
	 * 上位机通讯接口,返回应答
	 * 
	 * @param address
	 *            地址
	 * @param values
	 *            数据
	 * @param longIP
	 *            远程IP
	 * @param longPort
	 *            远程端口
	 * @param flagConn
	 *            是否连接
	 * @param flag
	 *            01充电 02放电 03停止
	 * @return Map 存放应答数据
	 */
	public static Map<String, String> getReply(GeneradeModel model) {
		byte[] b = new byte[8];
		b[0] = (byte) 0xAA;
		b[1] = (byte) 0x02;
		String address="";
		if(model.getFlag()==1||model.getFlag()==5){  //充电电压和放电电压
			address="0x0003";
		}else if(model.getFlag()==2||model.getFlag()==6){  //充电电流 和放电电流
			address="0x0004";
		}else if(model.getFlag()==3||model.getFlag()==7){  //充电功率和放电功率
			address="0x0008";
		}else if(model.getFlag()==4||model.getFlag()==8){  //点击开始或者停用
			address="0x0002";
		}
		
		
		byte[] addressBytes = UDPUtil.getstringToByte(address.substring(2,address.length()));
		b[2] = addressBytes[0];
		b[3] = addressBytes[1];
		String hData = ""; // 第四个的值
		String lData = ""; // 第四个的值
		if (address.equals("0x0002")) { // 工作状态
			b[4] = 0x00;
			hData = "00";
			if (model.getFlag()==4&&model.isCflagConn()) { // 充电
				b[5] = 0x01;
				lData = "01";
			} else if (model.getFlag()==8&&model.isCflagConn()) { // 放电
				b[5] = 0x02;
				lData = "02";
			} else if (!model.isCflagConn()){ // 停电
				b[5] = 0x03;
				lData = "03";
			}
		} else if (address.equals("0x0003") || address.equals("0x0008")) { // 0x0003  设定电压(普通模式)  0x0008  设定功率(普通模式)
			String values="";
			if(address.equals("0x0003")){   //设置电压
				if(model.getFlag()==1){     //充电电压
					values=Double.toString(model.getcVoltage());
				}else{                      //放电电压
					values=Double.toString(model.getfVoltage());
				}
			}else{  						//设定功率(普通模式)
				if(model.getFlag()==3){     //充电功率
					values=Double.toString(model.getcPower());
				}else{					   //放电功率
					values=Double.toString(model.getfPower());
				}
			}
			String hexValue = UDPUtil.voltageStrToByte(Double.valueOf(values), 10);
			b[4] = UDPUtil.getstringToByte(hexValue)[0];
			hData = hexValue.substring(0, 2);
			b[5] = UDPUtil.getstringToByte(hexValue)[1];
			lData = hexValue.substring(2, 4);
		} else if (address.equals("0x0004")) { // 设定电流(普通模式)
			String values="";
			if(model.getFlag()==2){   //充电电流
					values=Double.toString(model.getcCurrentA());
			}else{  //放电电流
					values=Double.toString(model.getfCurrentA());
			}
			String hexValue = UDPUtil.voltageStrToByte(Double.valueOf(values), 100);
			b[4] = UDPUtil.getstringToByte(hexValue)[0];
			hData = hexValue.substring(0, 2);
			b[5] = UDPUtil.getstringToByte(hexValue)[1];
			lData = hexValue.substring(2, 4);
		}
		// 验证码 校验和 2个字节(所有字节之和) = 首部 + 功能 + 数据+地址
		int sum = Integer.parseInt("AA", 16) + Integer.parseInt("02", 16) + Integer.parseInt(hData, 16)
				+ Integer.parseInt(lData, 16)+ Integer.parseInt(address.substring(2,address.length()), 16);
		String sumstr = Integer.toHexString(sum);
		if (sumstr.length() < 4) { // 验证码2个字节 ,小于4位就向前面补0
			String bu = "";
			// 不足4位,开始补0,到前面补
			for (int i = 0; i < 4 - sumstr.length(); i++) {
				bu += "0";
			}
			sumstr = bu + sumstr;
		}
		b[6] = UDPUtil.getstringToByte(sumstr)[0];
		b[7] = UDPUtil.getstringToByte(sumstr)[1];
		Map<String, String> map = new HashMap<>();
		
		Map<String, String> maps = UDPUtil.send(model.getLongIP(), model.getLongPort(), map, b);
		return maps;
	}

	/**
	 * 数据转换成字节数组 (如前端电压,电流,功率转换)
	 * 
	 * @param v
	 *            数据
	 * @param multiple
	 *            电压
	 * @return
	 */
	public static String voltageStrToByte(Double v, int multiple) {
		String voltage = "";
		v = v * multiple;
		voltage = Integer.toHexString(v.intValue()).toUpperCase(); // 电压四位不足4位,开始补0,到前面补
		if (voltage.length() < 4) {
			String bu = "";
			// 不足4位,开始补0,到前面补
			for (int i = 0; i < 4 - voltage.length(); i++) {
				bu += "0";
			}
			voltage = bu + voltage;
		}
		return voltage;
	}
	
	/**
	 * 设置可编辑模式
	 * @param model
	 * @return
	 */
	public static Map<String, String> setEditModelList(EditSaveModelVo saveModelVo) {
		//判断是否是嵌套循环
		if(saveModelVo.getRowList().size()>0){    //嵌套
			for (RowModel rowModel : saveModelVo.getRowList()) {
				List<EditModel> model=new ArrayList<>();
				for (EditModel editModel : saveModelVo.getUserList()) {
					Integer id=Integer.valueOf(editModel.getId());
					if(id>=rowModel.getStartRow()&&id<=rowModel.getEndRow()){
						if(!model.contains(editModel.getId())){
							model.add(editModel);
						}
						
					}
				}
				
				//循环次数
				for (int i = 0; i < rowModel.getForCount(); i++) {
					forTableData(model);
				}
			}
     	}else{    //非嵌套
			forTableData(saveModelVo.getUserList());
		}
		return null;
	}
   
	/**
	 * 循环打印表的数据
	 * @param model
	 */
	private static void forTableData(List<EditModel> model) {
		//循环可编辑模式表格内容,只有勾选的才需要运行
		for (EditModel editModel : model) {
			if(editModel.isCheckState()==true){
				//首先,查看可编辑模式列表的一行数据是否为搁置状态
				if(editModel.getTypeNumber().equals("03")){//搁置
					GeneradeModel generadeModel=new GeneradeModel();
					generadeModel.setLongIP(editModel.getLongIP());
					generadeModel.setLongPort(editModel.getLongPort());
					generadeModel.setFlagConn(generadeModel.isFlagConn());
					generadeModel.setCflagConn(false);
					generadeModel.setFlag(4);
					Map<String, String> map= UDPUtil.getReply(generadeModel);
					sleepTime(editModel.getContinuousTime());
				}else{
					//y=kx+b
					double k=0;
					double b=0;
					long atimes=0;  //保存开始电流现在的时间点
					for (int i = 1; i <=4; i++) {
						GeneradeModel generadeModel=new GeneradeModel();
						generadeModel.setLongIP(editModel.getLongIP());
						generadeModel.setLongPort(editModel.getLongPort());
						generadeModel.setFlagConn(generadeModel.isFlagConn());
						if(i==2){      //电压类
							if(editModel.getTypeNumber().equals("01")){   //充电电压
								generadeModel.setcVoltage(editModel.getDevVoltage());
								generadeModel.setFlag(1);
							}else if(editModel.getTypeNumber().equals("02")){ //放电电压
								generadeModel.setfVoltage(editModel.getDevVoltage());
								generadeModel.setFlag(5);
							}
						}else if(i==3){   //功率类
							if(editModel.getTypeNumber().equals("01")){   //充电功率
								generadeModel.setcPower(editModel.getDevPower());
								generadeModel.setFlag(3);
							}else if(editModel.getTypeNumber().equals("02")){ //放电功率
								generadeModel.setfPower(editModel.getDevPower());
								generadeModel.setFlag(7);
							}
						}else if(i==1){   //开关类
							if(editModel.getTypeNumber().equals("01")){   //充电开关
								generadeModel.setCflagConn(true);
								generadeModel.setFlag(4);
							}else if(editModel.getTypeNumber().equals("02")){ //放电开关
								generadeModel.setFflagConn(true);
								generadeModel.setFlag(8);
							}
						}else if(i==4){   //电流类
							//电流类 第一次进这个代码块,需要算出  y=kx+b   y的值。b的值
							getCurrentA(editModel, generadeModel);
							
							//求出k.b的值
							k=(editModel.getDevEndCurrentA()-editModel.getDevStartCurrentA())/editModel.getContinuousTime();
							b=editModel.getDevEndCurrentA()-(editModel.getContinuousTime()*k);
						}
						
						//发送指令
						if(UDPUtil.riskctrlSwith==true){
							Map<String, String> map= UDPUtil.getReply(generadeModel);
						}else{
							break;
						}
						atimes=System.currentTimeMillis();
					}
					System.out.println("UDPUtil.riskctrlSwith:"+UDPUtil.riskctrlSwith);
					
					if(editModel.getContinuousTime()!=0.0){   //持续时间
						Date afterDate=null; 
						int count=1; //计数 判断循环几次
						double y=0;
						do{
							count++;
							y=k*((System.currentTimeMillis()-atimes)/1000)+b;  //y是电流
							afterDate=new Date((long) (atimes+editModel.getContinuousTime()*(1000)));
							//发送指令
							GeneradeModel generadeModel=new GeneradeModel();
							generadeModel.setLongIP(editModel.getLongIP());
							generadeModel.setLongPort(editModel.getLongPort());
							generadeModel.setFlagConn(generadeModel.isFlagConn());
							if(editModel.getTypeNumber().equals("01")){   //电流
								generadeModel.setcCurrentA(y);
								generadeModel.setFlag(2);
							}else if(editModel.getTypeNumber().equals("02")){ //电流
								generadeModel.setfCurrentA(y);
								generadeModel.setFlag(6);
							}
							if(UDPUtil.riskctrlSwith==true){
								Map<String, String> map= UDPUtil.getReply(generadeModel);
							}else{
								break;
							}
						}while(System.currentTimeMillis() < afterDate.getTime());
						
						//最后一次
						if(y<editModel.getDevEndCurrentA()){
							GeneradeModel generadeModel=new GeneradeModel();
							generadeModel.setLongIP(editModel.getLongIP());
							generadeModel.setLongPort(editModel.getLongPort());
							generadeModel.setFlagConn(generadeModel.isFlagConn());
							if(editModel.getTypeNumber().equals("01")){   //电流
								generadeModel.setcCurrentA(editModel.getDevEndCurrentA());
								generadeModel.setFlag(2);
							}else if(editModel.getTypeNumber().equals("02")){ //电流
								generadeModel.setfCurrentA(editModel.getDevEndCurrentA());
								generadeModel.setFlag(6);
							}
							if(UDPUtil.riskctrlSwith==true){
								Map<String, String> map= UDPUtil.getReply(generadeModel);
							}else{
								break;
							}
						}
						
					}
					
				}
			}
			if(UDPUtil.riskctrlSwith==false){
				break;
			}
		}
	}
     
	/**
	 * 获取电流
	 * @param editModel
	 * @param generadeModel
	 */
	private static void getCurrentA(EditModel editModel, GeneradeModel generadeModel) {
		if(editModel.getTypeNumber().equals("01")){   //电流
			generadeModel.setcCurrentA(editModel.getDevStartCurrentA());
			generadeModel.setFlag(2);
		}else if(editModel.getTypeNumber().equals("02")){ //电流
			generadeModel.setfCurrentA(editModel.getDevStartCurrentA());
			generadeModel.setFlag(6);
		}
	}

	/**
	 * 延迟几秒后运行
	 * @param seconds
	 */
	private static void sleepTime(double seconds) {
		Date startTime = new Date();
		Date afterDate=null;
		do {
			afterDate = new Date((long) (startTime.getTime()+(seconds*1000)));
		} while (System.currentTimeMillis() < afterDate.getTime());
	}
	
	/**
	 * 获取仪器模块的测试值
	 * @param addressLength 地址长度     一个字节   不够两位补0,格式01
	 * @param startAddress  开始地址    两个字节   0x0001
	 * @return
	 */
	public static Map<String, String> gainInstrumentValue(ServerInfoModel model,String addressLength,String startAddress){
		startAddress=startAddress.substring(2, startAddress.length());
		byte[] b=new byte[7];
		b[0]=(byte) 0xAA;     //首部
		b[1]=(byte) 0x06;	  //功能码
		b[2]=UDPUtil.getstringToByte(addressLength)[0];
		b[3]=UDPUtil.getstringToByte(startAddress)[0];
		b[4]=UDPUtil.getstringToByte(startAddress)[1];
		int sum=Integer.parseInt("AA", 16) + Integer.parseInt("06", 16) + Integer.parseInt(addressLength, 16)
		+ Integer.parseInt(startAddress.substring(0,2), 16)+ Integer.parseInt(startAddress.substring(2,4), 16);
		
		String sumstr = Integer.toHexString(sum);
		if (sumstr.length() < 4) { // 验证码2个字节 ,小于4位就向前面补0
			String bu = "";
			// 不足4位,开始补0,到前面补
			for (int i = 0; i < 4 - sumstr.length(); i++) {
				bu += "0";
			}
			sumstr = bu + sumstr;
		}
		b[5]=UDPUtil.getstringToByte(sumstr)[0];
		b[6]=UDPUtil.getstringToByte(sumstr)[1];
		Map<String, String> map = new HashMap<>();
		Map<String, String> maps = UDPUtil.send(model.getLongIP(), model.getLongPort(), map, b);
		if(maps.get("state").equals("N")){
			logger.info("获取仪器模块的测试值操作"+maps.get("desc"));
		}else{    //读取成功     AA 06 05 00 01 00 B6
			//AA 06 05 00 01        00 00 00 00 00 00 00 10 00 04 00 CA
			//报警信息解析   1.把返回的十六进制的值先转未2进制,不够16位,前面补0,再反转
			//         2。再查看值未1对应的bit的值
			String str=map.get("data");
			if(str!=null){
				str=str.replaceAll(" ", "");
				
				if(str.substring(2,4).equals("06")){   //再次确保接收到值没有问题
					System.out.println("str:"+str);
					String voltage=str.substring(10,14);   //测量电压
					String current=str.substring(14,18);   //测量电流
					String power=str.substring(18,22);	   //测量功率
					String warnInfomation=str.substring(22,26);//报警信息
					String runState=str.substring(28,30);//运行状态
					
					warnInfomation=new StringBuilder(hexString2binaryString("0010")).reverse().toString();
					
					int warnInfomationIndex=warnInfomation.indexOf("1");
					//打印到前端预警信息的值
					String warnInfoValues="";
					warnInfoValues = printWarnInfomation(warnInfomationIndex, warnInfoValues);
					//0x01:充电, 0x02:放电, 0x03:搁置, 0x04:停止
					if(runState.equals("01")){
						runState="充电";
					}else if(runState.equals("02")){
						runState="放电";
					}else if(runState.equals("03")){
						runState="搁置";
					}else if(runState.equals("04")){
						runState="停止";
					}
					maps.put("voltage",hexTodecimal(voltage,10));
					maps.put("current",hexTodecimal(current,100));
					maps.put("power",hexTodecimal(power,10));
					maps.put("warnInfomation",warnInfoValues);
					maps.put("runState",runState);
					List<MeasurementModelVo> models=null;
					//判断是否第一次加入缓存
					if(MeasurementCache.getMeasurementMap("measurement")==null){  
						models=new ArrayList<>();
					}else{
						models=MeasurementCache.getMeasurementMap("measurement");
					}
					MeasurementModelVo modelVo=new MeasurementModelVo();
					modelVo.setCurrent(hexTodecimal(current,100));
					SimpleDateFormat currentTime=new SimpleDateFormat("yyyyMMddHHmmss");
					modelVo.setCurrentTime(currentTime.format(new Date()));
					modelVo.setPower(hexTodecimal(power,10));
					modelVo.setVoltage(hexTodecimal(voltage,10));
					models.add(modelVo);
					MeasurementCache.setMeasurementMap("measurement", models);
				}else{
					initMeasurement(maps);
				}
			}else{
				initMeasurement(maps);
			}
		}
		return maps;
	}
   
	/**
	 * 初始化为空的数据
	 * @param maps
	 */
	private static void initMeasurement(Map<String, String> maps) {
	/*	maps.put("voltage","0.0");
		maps.put("current","0.00");
		maps.put("power","0.0");
		maps.put("warnInfomation","");
		maps.put("runState","" );
		List<MeasurementModelVo> models=null;
		//判断是否第一次加入缓存
		if(MeasurementCache.getMeasurementMap("measurement")==null){  
			models=new ArrayList<>();
		}else{
			models=MeasurementCache.getMeasurementMap("measurement");
		}
		MeasurementModelVo modelVo=new MeasurementModelVo();
	
		modelVo.setCurrent("0.00");
		SimpleDateFormat currentTime=new SimpleDateFormat("yyyyMMddHHmmss");
		modelVo.setCurrentTime(currentTime.format(new Date()));
		modelVo.setPower("0.0");
		modelVo.setVoltage("0.0");
		models.add(modelVo);
		MeasurementCache.setMeasurementMap("measurement", models);*/
		if(TestCache.measurementMap.get("cesi")==null){
			TestCache.measurementMap.put("cesi",1.1);
		}else{
			TestCache.measurementMap.put("cesi",TestCache.measurementMap.get("cesi")+1);
		}

		maps.put("voltage",String.valueOf(TestCache.measurementMap.get("cesi")+1));
		maps.put("current",String.valueOf(TestCache.measurementMap.get("cesi")+1.1));
		maps.put("power",String.valueOf(TestCache.measurementMap.get("cesi")+1.2));
		maps.put("warnInfomation","");
		maps.put("runState","" );
		List<MeasurementModelVo> models=null;
		//判断是否第一次加入缓存
		if(MeasurementCache.getMeasurementMap("measurement")==null){  
			models=new ArrayList<>();
		}else{
			models=MeasurementCache.getMeasurementMap("measurement");
		}
		MeasurementModelVo modelVo=new MeasurementModelVo();
	
		modelVo.setCurrent(String.valueOf(TestCache.measurementMap.get("cesi")+1.1));
		SimpleDateFormat currentTime=new SimpleDateFormat("yyyyMMddHHmmss");
		modelVo.setCurrentTime(currentTime.format(new Date()));
		modelVo.setPower(String.valueOf(TestCache.measurementMap.get("cesi")+1.2));
		modelVo.setVoltage(String.valueOf(TestCache.measurementMap.get("cesi")+1));
		models.add(modelVo);
		MeasurementCache.setMeasurementMap("measurement", models);
	}
 
	/**
	 * 封装打印预警信息的值
	 * @param warnInfomationIndex   下标位置
	 * @param warnInfoValues    输出的值
	 * @return 
	 */
	private static String printWarnInfomation(int warnInfomationIndex, String warnInfoValues) {
		if(warnInfomationIndex!=-1){   //说明有预警
			if(warnInfomationIndex==1){
				warnInfoValues="温度过高";
			}else if(warnInfomationIndex==2){
				warnInfoValues="充电电流过大";
			}else if(warnInfomationIndex==3){
				warnInfoValues="放电电流过大";
			}else if(warnInfomationIndex==4){
				warnInfoValues="EVC通讯错误";
			}else if(warnInfomationIndex==6){
				warnInfoValues="DC报警";
			}else if(warnInfomationIndex==7){
				warnInfoValues="pfc报警";
			}else if(warnInfomationIndex==8){
				warnInfoValues="配置电压电流发送失败停机";
			}else if(warnInfomationIndex==9){
				warnInfoValues="启动命令发送失败停机";
			}else if(warnInfomationIndex==10){
				warnInfoValues="电流过小或EVC未启动,停机";
			}
			
		}
		return warnInfoValues;
	};
	
	/**
	 * 十六进制转十直径 ,并对电压电流功率进行特殊处理
	 * @param values   参数的值
	 * @param multiple  倍数  
	 * @return
	 */
	public static String hexTodecimal(String values,int multiple){
		double str=Double.valueOf(Integer.valueOf(values,16)/10)/multiple;
		return String.valueOf(str);
	};
	
	
	/**
	 * 将十六进制字符串转为2进制字符串,不够用0补位
	 * @param hexString
	 * @return
	 */
    public static String hexString2binaryString(String hexString){  
        if (hexString == null || hexString.length() % 2 != 0) 
            return null;  
        String bString = "", tmp;  
        for (int i = 0; i < hexString.length(); i++){  
            tmp = "0000"  
                    + Integer.toBinaryString(Integer.parseInt(hexString  
                            .substring(i, i + 1), 16));  
            bString += tmp.substring(tmp.length() - 4);  
        }  
        return bString;  
    }  
	
	
	public static int getPort() {
		return port;
	}

	public static void setPort(int port) {
		UDPUtil.port = port;
	}
	 
	/**
	 * 自动追加文件
	 * @param content
	 */
	 public static void appendToTxt(String content) {  
		 FileWriter writer;
		try {
			writer = new FileWriter(UDPUtil.class.getResource("/").getFile()+"/com/parna/util/autofile.txt", true);
			writer.write(content+"\r\n");
	        writer.close();
		} catch (IOException e) {
			logger.info("自动保存写入失败!"+e.getMessage());
		}     
	
	}  
	
	public static void main(String[] args) throws IOException {
		String a="AA0200040397014A";
		System.out.println(a.substring(2,4));
	}
}

2.接收线程

       专门用来监听接收过来的数据。

package com.parna.util;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DecimalFormat;

public class ReceiveSocket implements Runnable {
	public static DatagramSocket receiveSocket = null;
	public static String printString="";

	public DatagramSocket getReceiveSocket() {
		return receiveSocket;
	}

	public void setReceiveSocket(DatagramSocket receiveSocket) {
		this.receiveSocket = receiveSocket;
	}

	public ReceiveSocket(DatagramSocket receiveSocket) {
		super();
		this.receiveSocket = receiveSocket;
	}

	@Override
	public void run() {
/*		while (true) {*/
				byte[] b = new byte[50];
				DatagramPacket packet = new DatagramPacket(b, b.length);
				try {
					receiveSocket.receive(packet);
					printString = UDPUtil.receivePrint(packet);
				} catch (IOException e) {
				/*	e.printStackTrace();*/
				/*	System.out.println("端口被占用或连接已关闭!!!");*/
					return;
				}
/*		}*/
	}

	public static void main(String[] args) throws UnknownHostException {
          System.out.println(InetAddress.getLocalHost().getHostAddress());
	}
}

注意:因为我这里使用的udp协议,使用是一开一关的方式(中间听留10ms,具体停留的时间需要跟客户端商量),专门用来接收值,建议是做缓存处理,把发送列表和接收列表都报错起来,通过业务逻辑判断发送是否成功。