c# - 有效拆分以分隔符分隔的消息

标签 c# stream

我想要一种内存高效且省时的方法来根据分隔符拆分传入的数据流。流是网络流,传入的“消息”由 CRLF 拆分。以前我通过使用 UTF8 将传入数据转换为字符串来完成此操作,然后检查 CRLF,如果它存在,我会根据它进行拆分,但是,这不是解决问题的好方法,因为越来越多的消息是传入。此外,我可能会得到包含 1 条消息的数据 block ,也可能会得到包含 10 条消息的数据 block ,甚至一些只包含部分消息的数据 block 。

这就是我到目前为止想到的。使用内存流作为缓冲区,当数据进入时,将数据读入内存流。如果找到定界符 (CRLF),我会获取内存流中的所有数据,并调用 messageReceived,然后继续。对此有什么想法吗?

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

最佳答案

我认为您的想法是正确的。只需使用字节数组即可。

这是我的做法,完全未经测试,可以优化....

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
   {
       int i = 0;
       for(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();
}

关于c# - 有效拆分以分隔符分隔的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5761618/

相关文章:

c# - 停止卡在阻塞调用中的线程

java - PushbackInputStream 和标记/重置

C++流负数转换

actionscript-3 - AS3 mp4 保存文件

C++ : Ignoring multiple << Operators in a line

c# - 在 foreach 循环中修改集合时出现异常

c# - LINQ Where() 和 FirstOrDefault() 之间的逻辑区别

c# - 在 C# 中使用进度条

c# - "standard"初始化基于 COM 的库的方法是什么

php - 使用自定义流包装器作为 PHP 的 http ://stream wrapper 的测试 stub