YModem发送端C#实现

1原理:
20140610144426187

2代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Windows.Forms;
using System.IO;

namespace LangRuiSteel.Helper
{
    public class YmodemHelper
    {
        private const byte MODEM_SOH = 0x01;    //数据块起始字符
        private const byte MODEM_STX = 0x02;    //1024字节开始
        private const byte MODEM_EOT = 0x04;    //文件传输结束
        private const byte MODEM_ACK = 0x06;    //确认应答
        private const byte MODEM_NAK = 0x15;    //出现错误
        private const byte MODEM_CAN = 0x18;    //取消传输
        private const byte MODEM_C = 0x43;      //大写字母C

        private TextBox textBox1;
        private SerialPort serialPort;
        private List<byte[]> list = new List<byte[]>();

        public YmodemHelper(string portName, int baudRate, string filePath, TextBox tb)
        {
            ReadFile(filePath);
            textBox1 = tb;
            serialPort = new SerialPort();
            serialPort.PortName = portName;
            serialPort.BaudRate = baudRate;
            serialPort.DataReceived += SerialPort_DataReceived;
            serialPort.Open();
        }

        public void start()
        {
            byte[] buf = { 0x31 };
            serialPort.Write(buf, 0, buf.Length);
        }

        private void Shut()
        {
            serialPort.Close();
        }

        private delegate void MyDele(string mes);
        private void ShowText(string mes)
        {
            if (textBox1.InvokeRequired)
                textBox1.BeginInvoke(new MyDele(ShowText), new object[] { mes });
            else
                textBox1.AppendText(mes + "\r\n");
        }

        private void SendData(byte[] buffer)
        {
            serialPort.Write(buffer, 0, buffer.Length);
        }

        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int count = serialPort.BytesToRead;
            if (count > 0)
            {
                byte[] buffer = new byte[count];
                serialPort.Read(buffer, 0, count);

                switch (buffer[0])
                {
                    case MODEM_C:
                        ShowText("START");
                        SendData(list[0]);
                        ShowText("SEND " + list.Count);
                        break;
                    case MODEM_ACK:
                        if (list.Count > 1)
                        {
                            list.RemoveAt(0);
                            SendData(list[0]);
                            ShowText("SEND " + list.Count);
                        }
                        if (buffer.Length > 1 && buffer[1] == MODEM_C && list.Count == 1)
                        {
                            ShowText("SHUT");
                            this.Shut();
                        }
                        break;
                    case MODEM_NAK:
                        SendData(list[0]);
                        ShowText("STOP");
                        break;
                }
            }
        }

        private void ReadFile(string filepath)
        {
            FileInfo fi = new FileInfo(filepath);
            FileStream fs = File.Open(filepath, FileMode.Open);
            byte[] buffer = new byte[fs.Length];
            fs.Read(buffer, 0, buffer.Length);
            fs.Close();
            string fn = fi.Name;
            string cd = Convert.ToString(buffer.Length);

            byte[] fnb = Encoding.UTF8.GetBytes(fn);
            byte[] fnc = Encoding.UTF8.GetBytes(cd);
            byte[] all = new byte[fnb.Length + fnc.Length + 1];
            Array.Copy(fnb, 0, all, 0, fnb.Length);
            Array.Copy(fnc, 0, all, fnb.Length + 1, fnc.Length);
            list.Add(GetData(all));
            int index = 0;
            while (index < buffer.Length)
            {
                int l = Len1;
                if (buffer.Length - index < Len1)
                    l = buffer.Length - index;
                byte[] tmp = new byte[l];
                Array.Copy(buffer, index, tmp, 0, tmp.Length);
                index += l;
                list.Add(GetData(tmp));
            }
            list.Add(new byte[] { MODEM_EOT });
        }

        private int Len1 = 1024;
        private byte XUHAO = 0;

        private byte[] GetData(byte[] buffer)
        {
            if (buffer.Length > Len1)
                return null;

            byte[] tmp = new byte[Len1 + 2];
            Array.Copy(buffer, tmp, buffer.Length);
            CrcHelper.ConCRC(ref tmp, tmp.Length - 2);

            byte[] buf = new byte[Len1 + 5];
            buf[0] = MODEM_STX;
            buf[1] = XUHAO;
            buf[2] = (byte)~XUHAO;
            Array.Copy(tmp, 0, buf, 3, tmp.Length);
            XUHAO++;

            return buf;
        }
    }
}

Android生命周期

点击打开时 creat start resume
点返回退出时 pause stop destroy
———————————
处于打开时
点HOME或被别的Activity挡住时 pause stop
点返回或再次打开时 start resume
———————————
被别的程序的Dialog遮挡时 pause
取消遮挡后 resume
———————————
被自己的Dialog遮挡时不会有任何事件