c#用串口传输二进制文件 xmodem协议

代码是项目中拷出来的,俗称刷机软件,绝对可用,缺少的控件和变量名自己补齐就好

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Net;                                                       //引入socket命名
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.VisualBasic;

1、第一步,打开二进制文件并存为list

  OpenFileDialog openFileDialog1 = new OpenFileDialog(); //定义打开文本位置的类

            openFileDialog1.Filter = "Bin Files (.bin)|*.bin|所有文件 (*.*)|*.*";//文件筛选器的设定
            openFileDialog1.FilterIndex = 1;
            openFileDialog1.FileName = "";
            openFileDialog1.ShowReadOnly = true;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                tbx_FileName.Text = openFileDialog1.FileName;
                try
                {
                    Open_File_list.Clear();

                    FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open);//初始化文件流

                    BinaryReader sr = new BinaryReader(fs);
                    sr.BaseStream.Seek(0, SeekOrigin.Begin);

                    Open_File_array_length = (int)fs.Length;

                    for (int i = 0; i < Open_File_array_length; i++)
                    {
                        byte tmp = sr.ReadByte();
                        Open_File_list.Add(tmp);
                    }
                    //关闭此StreamReader对象 
                    sr.Close();
                    fs.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return;
                }
            }

2、第二步创建一个线程发送list,用到xmodem协议

private void sendFile()
        {
            ComThread_Run_Flag = false;
            btn_SendFile.Enabled = false;
            Timer1_Run_Flag = true;
            rcv_buffer = new byte[255]; //创建数字缓存区
            send_buffer = new byte[1029]; //创建缓存区  1024 for XModem 1k + 3 head chars + 2 crc
            packetno = 1;
            complate_sz = 0;        //已经发送的字节数
            totle_sz = 0;           //需要发送数据包的长度
            remnant_sz = 0;         //剩余长度
            complate = false;      //发送完成标志位
            done = true;    //串口发送文件结束的标记
            //string return_data = "";    //返回值
            Send_Times = 0;         //重发次数

            while (done)
            {
                Thread.Sleep(10);
                Per_Sec_Count++;
                if (Per_Sec_Count > MAX_WAIT_C_SEC * 500)
                {
                    done = false;
                    Per_Sec_Count = 0;
                    btn_SendFile.Enabled = true;
                    ComThread_Run_Flag = true;
                    //Timer1_Run_Flag = false;
                    toolStripProgressBar1.Value = 0;//设置当前值
                    MessageBox.Show("接收超时", "发送文件", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                int rcv_DataLen = serialPort1.BytesToRead; //接收的字节数

                if (rcv_DataLen > 0)
                {
                    serialPort1.Read(rcv_buffer, 0, rcv_DataLen);//把数据读入缓存区
                    //Console.WriteLine("rcv_buffer0:{0}", rcv_buffer[0].ToString("X2") + " ");
                    //AddContent(rcv_buffer[0].ToString("X2")+"\n", "Green");
                   // Console.WriteLine("totle_sz:{0}  complate_sz:{1}   remnant_sz{2}", totle_sz, complate_sz, remnant_sz);
                    AddContent("<"+DateTime.Now.ToString ("HH:mm:ss")+">"  +"已完成:"+complate_sz+"/"+totle_sz+"\n" ,"Green");
                    //this.AddData(rcv_buffer, rcv_DataLen);//输出显示数据
                    //  BarCountRx.Text = Convert.ToString(Convert.ToInt32(BarCountRx.Text) + rcv_DataLen); //接收字节计数
                    rcv_DataLen += rcv_buffer.Length;
                    BarCountRx.Text = Convert.ToString(rcv_DataLen); //接收字节计数


                    if (rcv_buffer[0] == POLL)
                    {
                        Per_Sec_Count = 0;
                        totle_sz = Open_File_array_length;
                        packetno = 1;
                        complate_sz = 0;
                        Send_Times = 0;
                        toolStripProgressBar1.Maximum = (int)totle_sz;
                        toolStripProgressBar1.Value = 0;//设置当前值
                        goto send_data;
                    }
                    else if (rcv_buffer[0] == ACK)
                    {
                        Per_Sec_Count = 0;
                        complate_sz = complate_sz + remnant_sz;
                        toolStripProgressBar1.Value = complate_sz;
                        toolStripStatusLabel3.Text = (Convert.ToDouble(complate_sz) / Convert.ToDouble(totle_sz)*100).ToString().Substring(0,2) + "%";
                        if (complate_sz < totle_sz)
                        {
                            Send_Times = 0;
                            packetno++;
                            goto send_data;
                        }
                        else
                        {
                            if (complate == true)
                            {
                                done = false;
                                Per_Sec_Count = 0;
                                btn_SendFile.Enabled = true;
                                ComThread_Run_Flag = true;
                                //Timer1_Run_Flag = false;
                                toolStripProgressBar1.Value = 0;//设置当前值
                                MessageBox.Show("发送完成", "发送文件", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                flag_time = true;
                                beforDT = System.DateTime.Now;

                                return;
                            }
                            else
                            {
                                goto send_data;
                            }
                        }
                    }
                    else if (rcv_buffer[0] == NAK)
                    {
                        Per_Sec_Count = 0;
                        goto send_data;
                    }
                    else if (rcv_buffer[0] == CAN)
                    {
                        done = false;
                        Per_Sec_Count = 0;
                        btn_SendFile.Enabled = true;
                        ComThread_Run_Flag = true;
                        //Timer1_Run_Flag = false;
                        toolStripProgressBar1.Value = 0;//设置当前值
                        MessageBox.Show("强制结束", "发送文件", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }
                    else
                    {
                        done = false;
                        Per_Sec_Count = 0;
                        btn_SendFile.Enabled = true;
                        ComThread_Run_Flag = true;
                        //Timer1_Run_Flag = false;
                        toolStripProgressBar1.Value = 0;//设置当前值
                        MessageBox.Show("发送错误", "发送文件", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }

                send_data:
                    try
                    {
                        if (Send_Times < MAX_RSEND)
                        {
                            send_buffer[0] = STX;
                            send_buffer[1] = packetno;
                            send_buffer[2] = (byte)(~packetno);
                            remnant_sz = totle_sz - complate_sz;
                            if (remnant_sz > Per_Pack_Sz)
                            {
                                remnant_sz = Per_Pack_Sz;
                            }
                            if (remnant_sz > 0)
                            {
                                //Array.Copy(Open_File_array, complate_sz, send_buffer, 3, remnant_sz);

                                Open_File_list.CopyTo(complate_sz, send_buffer, 3, remnant_sz);
                                if (remnant_sz < Per_Pack_Sz)         //数据不足一包完整的数据包
                                {
                                    for (int i = 3 + remnant_sz; i < Per_Pack_Sz + 3; i++)
                                    {
                                        send_buffer[i] = CTRLZ;
                                    }
                                }

                                int CRC = u16CRCVerify(send_buffer, 3, Per_Pack_Sz);

                                send_buffer[Per_Pack_Sz + 3] = (byte)((CRC >> 8) & 0xFF);
                                send_buffer[Per_Pack_Sz + 4] = (byte)((CRC) & 0xFF);

                                for (int j = 0; j < Per_Pack_Sz + 5; j++)
                                {
                                    Console.Write(send_buffer[j].ToString("X2") + " ");
                                }
                                Console.WriteLine("");

                                this.serialPort1.Write(send_buffer, 0, Per_Pack_Sz + 5);
                                Send_Times++;
                            }
                            else
                            {
                                byte[] buffer2 = new byte[1];
                                buffer2[0] = EOT;
                                for (int j = 0; j < 1; j++)
                                {
                                    Console.Write(buffer2[j].ToString("X2") + " ");
                                }
                                Console.WriteLine("");

                                this.serialPort1.Write(buffer2, 0, 1);

                                complate = true;
                            }
                        }
                        else
                        {
                            done = false;
                            Send_Times = 0;
                            Per_Sec_Count = 0;
                            btn_SendFile.Enabled = true;
                            ComThread_Run_Flag = true;
                            //Timer1_Run_Flag = false;
                            toolStripProgressBar1.Value = 0;//设置当前值
                            MessageBox.Show("发送错误", "发送文件", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        return;
                    }
                }
            }
        }

猜你喜欢

转载自blog.csdn.net/u014194297/article/details/92806275
今日推荐