C#高性能大容量SOCKET并发(七):协议字符集

原文:C#高性能大容量SOCKET并发(七):协议字符集

UTF-8

UTF-8是UNICODE的一种变长字符编码又称万国码,由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编码UNICODE字符。用在网页上可以同一页面显示中文简体繁体及其它语言(如日文,韩文)。

使用UTF-8的好处是现在一些手机平台都是使用UTF-8,另外在一些嵌入式平台,如果不支持中文,只支持英文,可以不转换,UTF-8就可以识别。

NET默认支持的编码是Unicode,为了支持UTF-8,需要转换下,为了编程简便性,我们只在发包和解包的地方进行UTF-8转换。

收包把UTF-8转为UNICODE

收包我们需要在分包完成后,把内存数组是UTF-8编码转换为Unicode,即为C#的string,后续的处理就都可以基于string进行处理,比较方便。

        public virtual bool ProcessPacket(byte[] buffer, int offset, int count) //处理分完包后的数据,把命令和数据分开,并对命令进行解析
        {
            if (count < sizeof(int))
                return false;
            int commandLen = BitConverter.ToInt32(buffer, offset); //取出命令长度
            <span style="color:#ff6666;">string tmpStr = Encoding.UTF8.GetString(buffer, offset + sizeof(int), commandLen);</span>
            if (!m_incomingDataParser.DecodeProtocolText(tmpStr)) //解析命令
              return false;

            return ProcessCommand(buffer, offset + sizeof(int) + commandLen, count - sizeof(int) - commandLen); //处理命令
        }

发包把UNICODE转为UTF-8

发包我们主要调用DoSendResult,从发送缓冲中获取协议文本后,转换为UTF-8,然后写入发送列表中。

        public bool DoSendResult()
        {
            string commandText = m_outgoingDataAssembler.GetProtocolText();
            <span style="color:#ff6666;">byte[] bufferUTF8 = Encoding.UTF8.GetBytes(commandText);</span>
            int totalLength = sizeof(int) + bufferUTF8.Length; //获取总大小
            AsyncSendBufferManager asyncSendBufferManager = m_asyncSocketUserToken.SendBuffer;
            asyncSendBufferManager.StartPacket();
            asyncSendBufferManager.DynamicBufferManager.WriteInt(totalLength, false); //写入总大小
            asyncSendBufferManager.DynamicBufferManager.WriteInt(bufferUTF8.Length, false); //写入命令大小
            asyncSendBufferManager.DynamicBufferManager.WriteBuffer(bufferUTF8); //写入命令内容
            asyncSendBufferManager.EndPacket();

            bool result = true;
            if (!m_sendAsync)
            {
                int packetOffset = 0;
                int packetCount = 0;
                if (asyncSendBufferManager.GetFirstPacket(ref packetOffset, ref packetCount))
                {
                    m_sendAsync = true;
                    result = m_asyncSocketServer.SendAsyncEvent(m_asyncSocketUserToken.ConnectSocket, m_asyncSocketUserToken.SendEventArgs, 
                        asyncSendBufferManager.DynamicBufferManager.Buffer, packetOffset, packetCount);
                }                
            }
            return result;
        }

DEMO下载地址:http://download.csdn.net/detail/sqldebug_fan/7467745
免责声明:此代码只是为了演示C#完成端口编程,仅用于学习和研究,切勿用于商业用途。水平有限,C#也属于初学,错误在所难免,欢迎指正和指导。邮箱地址:fansheng_hx@163.com。

上一篇:HTAP数据库 PostgreSQL 场景与性能测试之 31 - (OLTP) 高吞吐数据进出(堆存、行扫、无需索引) - 阅后即焚(读写大吞吐并测)


下一篇:在线教育场景下的点播试看功能实现