package ymodem; import baowen.Dell_udpReceive; import gnu.io.SerialPort; import index.JPanelMoudle.showDataComp; import index.JPanelMoudle.versionUpgradeComp; import tools.ChuanKou.SerialPortUtil; import tools.ShowMessage; import tools.Tools; import java.io.File; import java.io.IOException; import java.net.*; public class netWorkUpgradeThread extends Thread { private static byte[][] dataBytes; // 数据帧 private static byte[] startBytes; // 起始帧 private static byte[] endBytes ; // 结束帧 private static final long TIMEOUT = 600000; // 超过30秒未回应则退出升级模式 static int numSend = 0; static boolean SendDataFlag = false; static String ip = "";//目标设备ip地址 static int port;//目标设备端口 static DatagramSocket socket; static int bytlenth=1024; static DatagramPacket packet; public static void shengji(String ip1,int port1, String filePath1,byte[] byt,int nowPort){ SendDataFlag=false; numSend=0; ip = ip1; port = port1; Dell_udpReceive.sendData(byt,ip,port); ComSendUpdateFile(filePath1); Dell_udpReceive.stopThread();//暂停解析线程 chushihua(nowPort); new Dell_udpReceive(nowPort);//重新开始解析线程 } // 构造函数,接收串口和文件路径 public static void chushihua(int nowPort) { if (versionUpgradeComp.isWrite()) { if (socket==null){ try { socket = new DatagramSocket(nowPort);//创建socket byte[] data = new byte[bytlenth]; // 创建byte数组 packet= new DatagramPacket(data,bytlenth); new netWorkUpgradeThread().startThread(); } catch (SocketException e) { throw new RuntimeException(e); } }else { new netWorkUpgradeThread().startThread(); } } } public void startThread() { Thread t = new Thread(this); t.start(); } public void run() { try { // 调用升级过程 upgtade(); stopThread(); } catch (Exception e) { Thread.currentThread().interrupt(); // 恢复中断标志 System.out.println("线程被中断,正在退出升级过程..."); e.printStackTrace(); } } //升级固件 private void upgtade(){ long startTime = System.currentTimeMillis(); boolean b = System.currentTimeMillis() - startTime < TIMEOUT; while (b&&!SendDataFlag) { // 等待回应 byte[] recDat = getRecDat(); // 如果设备没有回应(回应为空),则认为是超时 if (recDat == null || recDat.length == 0) { continue; } showDataComp.addAreaTextMes(recDat,ip,port); if (recDat[0] == ymodem.ACK) { numSend++; sendData(numSend); } else if (recDat[0] == ymodem.NAK || recDat[0] == ymodem.C) { // 收到NAK或CA,退出升级 sendData(numSend); }else if (recDat[0]==ymodem.CA){ break; } } versionUpgradeComp.exitUpgrade(); } //发送数据包 public static void sendData(int shuJuZhen) { int length = dataBytes.length; if (shuJuZhen == 0) { sendData(startBytes,ip,port); getProgress(shuJuZhen, length); } else if (shuJuZhen <= length && shuJuZhen > 0) { sendData(dataBytes[shuJuZhen - 1],ip,port); getProgress(shuJuZhen, length); } else if (shuJuZhen == length + 1||shuJuZhen == length + 2) { sendData(new byte[]{(byte) ymodem.EOT},ip,port); getProgress(shuJuZhen, length); } else if (shuJuZhen == length + 3) { sendData(endBytes,ip,port); getProgress(shuJuZhen, length); ShowMessage.zidingyi("升级完成"); SendDataFlag=true; numSend = 0; } } //计算当前包的进度 private static void getProgress(double shuJuZhen, int length) { int i =(int) Math.round((shuJuZhen / (length +3)) * 100); versionUpgradeComp.getJindu_SaoMiaoQi().setValue(i); } //获取要发送的帧数据 public static void ComSendUpdateFile(String filePath){ try { File file = new File(filePath); if (!file.exists()) { //如果文件不存在 ShowMessage.zidingyi("文件不存在" + filePath); //抛出文件找不到异常 return; } getFilesDataBytes.setNum(0); startBytes = getFilesDataBytes.getStartData(file);//获取起始帧数据包 dataBytes = getFilesDataBytes.getData(file);//获取数据帧数据包 endBytes = getFilesDataBytes.getEndData();//获取结束帧数据包 } catch (IOException e) { throw new RuntimeException(e); } } public static byte[] getRecDat() { byte[] dat = new byte[0]; try { dat = null; packet = new DatagramPacket(dat,100); socket.receive(packet); String hostAddress = packet.getAddress().getHostAddress(); if (hostAddress.equals(ip)){ int lenth=packet.getLength(); dat=subBytes(packet.getData(),0, lenth); } return dat; } catch (IOException e) { throw new RuntimeException(e); } } /**将数据发给网关*/ public static void sendData(byte[] data,String ipout,int portout) { DatagramPacket packet=null; InetAddress address=null; //如果数据类型相同 try { address=InetAddress.getByName(ipout); } catch (UnknownHostException e) { e.printStackTrace(); } packet=new DatagramPacket(data,data.length, address, portout); try { socket.send(packet); } catch (IOException e) { e.printStackTrace(); } } public static byte[] subBytes(byte[] src, int begin, int count) { byte[] bs = new byte[count]; System.arraycopy(src, begin, bs, 0, count); return bs; } public static void stopThread() { if (socket != null && !socket.isClosed()) { socket.close();//关闭socket对象 } } }