加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 高效拆分流中的分隔符分隔的消息

发布时间:2020-12-15 21:17:24 所属栏目:百科 来源:网络整理
导读:我想要一种基于分隔符分割传入数据流的内存高效且省时的方法.流是网络流,进入的“消息”由CRLF分割.以前我已经通过使用UTF8将incomming数据转换为字符串,然后检查CRLF,如果它存在我基于此分割,但是,这不是解决问题的一种非常好的方法,因为越来越多的消息是传
我想要一种基于分隔符分割传入数据流的内存高效且省时的方法.流是网络流,进入的“消息”由CRLF分割.以前我已经通过使用UTF8将incomming数据转换为字符串,然后检查CRLF,如果它存在我基于此分割,但是,这不是解决问题的一种非常好的方法,因为越来越多的消息是传入.此外,我可能会得到包含1条消息的数据块,并且我可能会获得包含10条消息的datachunks,甚至包含仅包含部分消息的消息.

所以这就是我到目前为止所想到的.将内存流用于缓冲区,当数据进入时将数据读入内存流.如果我找到了分隔符(CRLF),我会获取内存流中的所有数据,然后调用messageReceived,然后继续.有什么想法吗?

[编辑]
好吧,我想我需要更好地解释我想做什么.使用的协议是IRC协议1,它发送“消息”或“命令”,如果你想要,由CRLF分离.我在C#中使用带有BeginReceive和EndReceive的套接字类,所以一切都运行异步.我正在编写的类称为MessageConnection.它从tcp-socket接收数据,每当找到给定的分隔符(在本例中为CRLF)时,我希望它调用一个名为OnMessage的函数,将接收到的消息作为参数.我在使用StringBuilder作为缓冲区之前解决了完全相同的问题,并在每次收到数据时将新字符串附加到StringBuilder,然后我根据分隔符拆分StringBuilder返回的字符串,清空StringBuilder,以及插入拆分操作的最后一部分.之后,我循环使用split-array(没有最后一个元素)并调用OnMessage.这种方式感觉就像是一种解决问题的低效方式,因为我对字符串进行了大量的转换 – 据说不是很好,所以我想,需要有一种简单的方法来解决这个问题而不必在字符串中思考,只在字节数组中,只有当我有一个表示实际“消息”的字节数组时才转换为字符串,这就是我想要的帮助.

解决方法

我认为你确实有正确的想法.只需使用字节数组即可.

这是我如何做到的,纯粹未经测试,可以优化….

byte[] m_LongBuffer;
byte[] m_SmallBuffer;
void ReceiveCallback(IAsyncResult iar)
{
   //m_SmallBuffer contains the data read from the stream
   //Append it to m_LongBuffer
   int bytesread = socket.EndReceive(iar);
   m_LongBuffer = m_LongBuffer.Concat(m_SmallBuffer.Take(bytesread)).ToArray();

   int startpoint = 0;
   int splitpoint = 0;
   int lastendpoint = 0;
   bool twochar = false;

   do
   {
       for(int i=0;i<m_LongBuffer.Length;++i)
       {
           if((m_LongBuffer[i] == 0x0A) || (m_LongBuffer[i] == 0x0D))
           {
               splitpoint = i;
               if((m_LongBuffer[i+1] == 0x0A) || (m_LongBuffer[i+1] == 0x0D))
                    twochar=true;
               else
                    twochar=false;

               lastendpoint = splitpoint;                   
               String message = ASCII.ASCIIEncoding.GetString(m_LongBuffer.Skip(startpoint).Take(splitpoint - startpoint).ToArray());
               //Do something with the message
               startpoint = splitpoint + (twochar ? 2 : 1);
               break;
           }
       }
       if(i >= m_LongBuffer.Length)
            splitpoint = -1;
   } while (splitpoint != -1);
   m_LongBuffer = m_LongBuffer.Skip(lastendpoint).ToArray();
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读