Socket 字节缓冲区第二种方式

上一篇说到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了  
               }  
  
           }  
  
       }  



猜你喜欢

转载自blog.csdn.net/wyd1520/article/details/44153543
今日推荐