Socket 字节缓冲区第二种方式

来源:互联网 发布:神龙契约披风数据 编辑:程序博客网 时间:2024/06/05 11:10

上一篇说到Socket 的字节缓冲区里的 有包头、包长度、包尾,有些数据包只有包头与包尾而里面没有包长度,且这个包头包尾是多个字节组成的。这篇文章也是应CSDN某位网友的需求对这样的数据字节缓冲区进行改造一下,不多说了上代码

/// <summary>    /// 字节缓冲器    /// </summary>    public class ByteQueue    {        private List<byte> m_buffer = new List<byte>();        private byte[] headBuffer = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xCA, 0xCB, 0xCC, 0xCD }; //包头开始部份        private byte[] tailBuffer = new byte[] { 0xEA, 0xEB, 0xEC, 0xED };//包结束部份        private int IndexOf(List<byte> source, byte[] seach, int startIndex)        {            string baseStr = BitConverter.ToString(source.ToArray());            string searchStr=BitConverter.ToString(seach);    int index= baseStr.IndexOf(searchStr, startIndex);            return index==-1?-1 : index / 3;        }               public bool Find()        {            if (m_buffer.Count == 0)                return false;            int HeadIndex = IndexOf(m_buffer, headBuffer,0);//找开头的位置            if (HeadIndex == -1)            {                m_buffer.Clear();                return false; //没找到            }            else if (HeadIndex != 0) //不为开头移掉之前的字节            {                if (HeadIndex > 1)                {                    m_buffer.RemoveRange(0, HeadIndex);                    HeadIndex = 0;                }            }            int TailIndex = IndexOf(m_buffer, tailBuffer, headBuffer.Length); //查找结尾的位置            if (TailIndex == -1)            {                //这一步为防止连发一个开头的包后,没发结尾,而又发了一个包头                int head = IndexOf(m_buffer, headBuffer, 0);                if (head > -1)                {                    m_buffer.RemoveRange(0, head);                }                return false;            }            int packLength = TailIndex - HeadIndex;            if (packLength<0) //计算包尾是否与包长度相等            {                m_buffer.RemoveRange(0, TailIndex + tailBuffer.Length);                return false;            }            return true;        }               /// <summary>        /// 包长度        /// </summary>        /// <returns></returns>        private int GetLength()        {            int len = IndexOf(m_buffer, tailBuffer, headBuffer.Length) + tailBuffer.Length; //查找结尾的位置            return len;        }        /// <summary>        /// 提取数据        /// </summary>        public byte[]  Dequeue()        {            int length = GetLength();            List<byte> result = m_buffer.Take(length).ToList();//提取数据包            result.RemoveRange(0, headBuffer.Length);//移掉开头部份 只保留内容            result.RemoveRange(result.Count - tailBuffer.Length, tailBuffer.Length); //移掉结尾 只保留内容            m_buffer.RemoveRange(0, length);//缓冲区内容移除            return result.ToArray();                  }        /// <summary>        /// 队列数据        /// </summary>        /// <param name="buffer"></param>        public void Enqueue(byte[] buffer)        {            m_buffer.AddRange(buffer);        }    }


调用例子:

 

 public partial class MainForm : Form    {        public MainForm()        {            InitializeComponent();        }        ByteQueue queue = new ByteQueue();        private void button1_Click(object sender, EventArgs e)        {            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(textBox1.Text);            queue.Enqueue(CreatePack(buffer));                            }        private void button2_Click(object sender, EventArgs e)        {            queue.Enqueue(CreatePack(buffer));            while (queue.Find())            {                byte[] buffer = queue.Dequeue();                textBox2.Text += System.Text.Encoding.UTF8.GetString(buffer) + "\r\n";                          }          }        private byte[] CreatePack(byte[] body)        {            byte[] headbuff = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xCA, 0xCB, 0xCC, 0xCD };            byte[] tailbuff = new byte[] { 0xEA, 0xEB, 0xEC, 0xED };            byte[] buffer = new byte[headbuff.Length + tailbuff.Length + body.Length];            Buffer.BlockCopy(headbuff, 0, buffer, 0, headbuff.Length);            Buffer.BlockCopy(body, 0, buffer, headbuff.Length, body.Length);            Buffer.BlockCopy(tailbuff, 0, buffer, headbuff.Length + body.Length, tailbuff.Length);            return buffer;        }           }

放到串口或Socke的例子:


private ByteQueue queue = new ByteQueue();  private void socket_DataReceived(object sender, SerialDataReceivedEventArgs e)         {             int len = serialPort1.BytesToRead;             if (len > 0)             {                 byte[] temp = new byte[len];                 serialPort1.Read(temp, 0, len);                 queue.Enqueue(temp);                 while (queue.Find()) //while可处理同时接收到多个包                 {                     byte[] readBuffer =  queue.Dequeue();                     OnReceiveData(readBuffer); //<这里自己写一个委托吧就OK了                 }               }           }  



0 0
原创粉丝点击