java Ymodem协议上位机程序

本文介绍了一种使用Java实现Ymodem协议的方法,通过将文件名拓展为6个字节来表示版本号,并存储文件长度。第一帧数据包含SOH、版本号、文件长度和CRC校验。代码返回的是可以直接通过Netty发送的10进制byte数组。
摘要由CSDN通过智能技术生成

本文代码传入文件地址返回如代码块: 

 为了更好的拓展,我把foo.c这个文件名拓展成了6个字节用来表示版本号如1.2.66.c 

后四个字节用来存储文件长度

也就是说第0帧数据为 SOH 00 FF 1.2.66 1236542 NUL[118] CRC CRC

当然我最后返回的都是10进制的byte数组 可以直接netty发送

代码:

package com.ruoyi.netty.netty;

import com.ruoyi.netty.netty.domain.ByteUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.FileCopyUtils;

import java.io.*;

/**
 * @ClassName: Ymodem
 * @Description: Ymodem协议工具类
 * @author ns
 * @date 2021-10-18 14:25
 * @Copyright 873103468@qq.com
 */
public class Ymodem {

    /**
     * byte[]文件转Ymodem协议文件
     * @param file
     * @return
     */
    public static byte[][] BytesYmodem(byte[] file,double len,String name){
        byte[] bytestr = name.getBytes();
        int a=1;
        int b=254;
        int ys=(int)Math.ceil(len/128.00);
        if(bytestr.length!=6){
            return null;
        }
        byte[][] bytess=new byte[ys+1][133];
        bytess[0]=ymodem_0(bytestr,len);

        for (int bl=1;bl<ys;bl++){

            bytess[bl]=ymodemTobyte(file,bl,a,b,(int)len);
            a++;
            b--;
        }
        return bytess;
    }

    /***
     *  把文件地址转换成byte二维数组 二维数组例子
     *  (例子未转换实际已经转换)
     *  SOH 00 FF 00~00(共128个) CRCH CRCL
     *  SOH 01 FE 00~00(共128个) CRCH CRCL
     *  SOH 02 FD 00~00(共128个) CRCH CRCL
     *  SOH 03 FC 00~00(共128个) CRCH CRCL
     *  EOT
     *  EOT
     *  SOH 00 FF FUL[128] CRCH CRCL
     * @param path 文件地址
     * @return 最终数据
     */
    public static byte[][] getStringByteYmodem(String path){
        if (StringUtils.isNotEmpty(path)) {
            File file = new File(path);
            byte[] byte1 = fileToBinArray(file);
            int len=byte1.length;
            return BytesYmodem(byte1,len,getFileNameNoEx(file.getName()));
        }else {
            throw new RuntimeException("文件找不到地址");
        }
    }


    /**
     * 文件转为二进制数组
     * @param file
     * @return
     */
    public static byte[] fileToBinArray(File file){
        try {
            InputStream fis = new FileInputStream(file);
            byte[] bytes = FileCopyUtils.copyToByteArray(fis);
            return bytes;
        }catch (Exception ex){
            throw new RuntimeException("文件转为二进制数组出错",ex);
        }
    }

    /**
     * 第一帧
     * @param bytestr
     * @param len
     * @return
     */
    public static byte[] ymodem_0(byte[] bytestr,double len){
        //第一页
        byte[] b0= new byte[3];
        b0[0]=0x01;
        b0[1]=(byte) 00;
        b0[2]=(byte) 255;
        byte[] b1= new byte[128];
        ByteUtil.getByte2inByte1(b1,bytestr,0);
        byte[] b3= new byte[4];
        ByteUtil.putInt(b3,(int)len,0);
        ByteUtil.getByte2inByte1(b1,b3,6);
        ByteUtil.inMaxByte(b1,10);
        byte[] b5=ByteUtil.getByte1andByte2(b1,CRC.getCRC5(b1));
        return  ByteUtil.getByte1andByte2(b0,b5);
    }

    /**
     * 第n帧数据
     * @param file  文件
     * @param bl    第几行
     * @param a     01
     * @param b     FF
     * @param len   长度
     * @return
     */
    public static byte[] ymodemTobyte(byte[] file,int bl,int a,int b,int len){
        byte[] b0= new byte[3];
        b0[0]=0x01;
        b0[1]=(byte) a;
        b0[2]=(byte) b;
        byte[] sj= new byte[128];
        //判断剩余长度是否大于128时
        int lening=(bl-1)*128;
        int xhint =lening;
        if(len-lening<128){
            for (int f=0;f<len-lening;f++){
                sj[f]=file[xhint];
                xhint++;
            }
            ByteUtil.inMaxByte(sj,len-lening);
        }else {
            for (int f=0;f<128;f++){
                sj[f]=file[xhint];
                xhint++;
            }
        }
        byte[] sj1=ByteUtil.getByte1andByte2(sj,CRC.getCRC5(sj));
        return ByteUtil.getByte1andByte2(b0,sj1);
    }
    public static void main(String[] args) {
        System.out.println(getFileNameNoEx("1.2.66.c"));
    }
    /**
     * Java文件操作 获取文件扩展名

     */
    public static String getExtensionName(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot >-1) && (dot < (filename.length() - 1))) {
                return filename.substring(dot + 1);
            }
        }
        return filename;
    }
    /**
     * Java文件操作 获取不带扩展名的文件名
     */
    public static St
Ymodem协议是一种用于在计算机之间进行文件传输的通信协议。它是一种可靠性较高的协议,通过使用数据包序列号、校验和和重传机制来确保文件传输的准确性。 在使用Ymodem协议进行文件传输时,上位机是指发送文件的计算机,vc下载指的是使用Visual C++ (VC)编程语言进行文件下载。 要使用Ymodem协议上位机上实现VC下载,我们可以按照以下步骤进行: 1. 在VC编程环境中,创建一个新的项目,选择适当的文件传输相关函数库或插件。 2. 在项目中引入Ymodem协议的相关函数和类,这些函数和类通常是由编程语言自带或由第三方开发者提供。 3. 设置上位机与目标计算机之间的串口通信参数,例如波特率、数据位、校验位、停止位等。确保上位机与目标计算机之间可以进行有效的串口通信。 4. 实现文件选择和发送功能。在上位机中,通过与用户交互来选择要传输的文件,并将选定的文件发送到目标计算机。使用Ymodem协议,将文件切割成数据包,添加序列号和校验和,然后通过串口发送给目标计算机。 5. 实现文件接收功能。在目标计算机上,等待上位机发送文件。使用Ymodem协议,接收数据包,检查序列号和校验和,如果数据包有误,可以要求上位机重传。最终,将接收到的数据包合并成完整的文件。 6. 在文件传输过程中,可以显示传输进度条,以提供用户友好的界面和反馈。 7. 完成文件传输后,确保及时关闭串口连接,释放相关资源。 通过上述步骤,我们可以在VC编程环境中实现使用Ymodem协议进行文件下载的功能。这样能够确保传输的可靠性和准确性,使得文件传输过程更加方便和高效。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值