Socket 字节缓冲区第二种方式

来源:互联网 发布:c语言输出double类型 编辑:程序博客网 时间:2024/06/05 03:17

转载连接: http://blog.csdn.net/wyd1520/article/details/44153543


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

[csharp] view plain copy
  1. /// <summary>  
  2.     /// 字节缓冲器  
  3.     /// </summary>  
  4.     public class ByteQueue  
  5.     {  
  6.         private List<byte> m_buffer = new List<byte>();  
  7.         private byte[] headBuffer = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xCA, 0xCB, 0xCC, 0xCD }; //包头开始部份  
  8.         private byte[] tailBuffer = new byte[] { 0xEA, 0xEB, 0xEC, 0xED };//包结束部份  
  9.   
  10.         private int IndexOf(List<byte> source, byte[] seach, int startIndex)  
  11.         {  
  12.             string baseStr = BitConverter.ToString(source.ToArray());  
  13.             string searchStr=BitConverter.ToString(seach);  
  14.         int index= baseStr.IndexOf(searchStr, startIndex);  
  15.             return index==-1?-1 : index / 3;  
  16.         }  
  17.   
  18.          
  19.         public bool Find()  
  20.         {  
  21.             if (m_buffer.Count == 0)  
  22.                 return false;  
  23.             int HeadIndex = IndexOf(m_buffer, headBuffer,0);//找开头的位置  
  24.             if (HeadIndex == -1)  
  25.             {  
  26.                 m_buffer.Clear();  
  27.                 return false//没找到  
  28.             }  
  29.             else if (HeadIndex != 0) //不为开头移掉之前的字节  
  30.             {  
  31.                 if (HeadIndex > 1)  
  32.                 {  
  33.                     m_buffer.RemoveRange(0, HeadIndex);  
  34.                     HeadIndex = 0;  
  35.                 }  
  36.             }  
  37.   
  38.   
  39.   
  40.             int TailIndex = IndexOf(m_buffer, tailBuffer, headBuffer.Length); //查找结尾的位置  
  41.   
  42.             if (TailIndex == -1)  
  43.             {  
  44.                 //这一步为防止连发一个开头的包后,没发结尾,而又发了一个包头  
  45.                 int head = IndexOf(m_buffer, headBuffer, 0);  
  46.                 if (head > -1)  
  47.                 {  
  48.                     m_buffer.RemoveRange(0, head);  
  49.                 }  
  50.                 return false;  
  51.             }  
  52.             int packLength = TailIndex - HeadIndex;  
  53.             if (packLength<0) //计算包尾是否与包长度相等  
  54.             {  
  55.                 m_buffer.RemoveRange(0, TailIndex + tailBuffer.Length);  
  56.                 return false;  
  57.             }  
  58.             return true;  
  59.         }  
  60.   
  61.   
  62.   
  63.   
  64.          
  65.   
  66.         /// <summary>  
  67.         /// 包长度  
  68.         /// </summary>  
  69.         /// <returns></returns>  
  70.         private int GetLength()  
  71.         {  
  72.             int len = IndexOf(m_buffer, tailBuffer, headBuffer.Length) + tailBuffer.Length; //查找结尾的位置  
  73.             return len;  
  74.         }  
  75.         /// <summary>  
  76.         /// 提取数据  
  77.         /// </summary>  
  78.         public byte[]  Dequeue()  
  79.         {  
  80.             int length = GetLength();  
  81.             List<byte> result = m_buffer.Take(length).ToList();//提取数据包  
  82.             result.RemoveRange(0, headBuffer.Length);//移掉开头部份 只保留内容  
  83.             result.RemoveRange(result.Count - tailBuffer.Length, tailBuffer.Length); //移掉结尾 只保留内容  
  84.             m_buffer.RemoveRange(0, length);//缓冲区内容移除  
  85.             return result.ToArray();  
  86.             
  87.         }  
  88.   
  89.         /// <summary>  
  90.         /// 队列数据  
  91.         /// </summary>  
  92.         /// <param name="buffer"></param>  
  93.         public void Enqueue(byte[] buffer)  
  94.         {  
  95.             m_buffer.AddRange(buffer);  
  96.         }  
  97.     }  


调用例子:

 

[csharp] view plain copy
  1. public partial class MainForm : Form  
  2.    {  
  3.        public MainForm()  
  4.        {  
  5.            InitializeComponent();  
  6.        }  
  7.        ByteQueue queue = new ByteQueue();  
  8.   
  9.        private void button1_Click(object sender, EventArgs e)  
  10.        {  
  11.   
  12.            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(textBox1.Text);  
  13.            queue.Enqueue(CreatePack(buffer));  
  14.            
  15.            
  16.        }  
  17.        private void button2_Click(object sender, EventArgs e)  
  18.        {  
  19.            queue.Enqueue(CreatePack(buffer));  
  20.            while (queue.Find())  
  21.            {  
  22.   
  23.                byte[] buffer = queue.Dequeue();  
  24.                textBox2.Text += System.Text.Encoding.UTF8.GetString(buffer) + "\r\n";  
  25.                
  26.            }    
  27.        }  
  28.   
  29.        private byte[] CreatePack(byte[] body)  
  30.        {  
  31.            byte[] headbuff = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xCA, 0xCB, 0xCC, 0xCD };  
  32.            byte[] tailbuff = new byte[] { 0xEA, 0xEB, 0xEC, 0xED };  
  33.            byte[] buffer = new byte[headbuff.Length + tailbuff.Length + body.Length];  
  34.   
  35.            Buffer.BlockCopy(headbuff, 0, buffer, 0, headbuff.Length);  
  36.            Buffer.BlockCopy(body, 0, buffer, headbuff.Length, body.Length);  
  37.            Buffer.BlockCopy(tailbuff, 0, buffer, headbuff.Length + body.Length, tailbuff.Length);  
  38.            return buffer;  
  39.        }  
  40.   
  41.         
  42.    }  

放到串口或Socke的例子:


[csharp] view plain copy
  1. private ByteQueue queue = new ByteQueue();    
  2. private void socket_DataReceived(object sender, SerialDataReceivedEventArgs e)    
  3.        {    
  4.            int len = serialPort1.BytesToRead;    
  5.            if (len > 0)    
  6.            {    
  7.                byte[] temp = new byte[len];    
  8.                serialPort1.Read(temp, 0, len);    
  9.                queue.Enqueue(temp);    
  10.                while (queue.Find()) //while可处理同时接收到多个包    
  11.                {    
  12.                    byte[] readBuffer =  queue.Dequeue();    
  13.                    OnReceiveData(readBuffer); //<这里自己写一个委托吧就OK了    
  14.                }    
  15.     
  16.            }    
  17.     
  18.        }    

原创粉丝点击