所以这就是我到目前为止所想到的.将内存流用于缓冲区,当数据进入时将数据读入内存流.如果我找到了分隔符(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(); }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。