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进行处理,比较方便。

[csharp] view plain copy
  1. public virtual bool ProcessPacket(byte[] buffer, int offset, int count) //处理分完包后的数据,把命令和数据分开,并对命令进行解析  
  2. {  
  3.     if (count < sizeof(int))  
  4.         return false;  
  5.     int commandLen = BitConverter.ToInt32(buffer, offset); //取出命令长度  
  6.     <span style="color:#ff6666;">string tmpStr = Encoding.UTF8.GetString(buffer, offset + sizeof(int), commandLen);</span>  
  7.     if (!m_incomingDataParser.DecodeProtocolText(tmpStr)) //解析命令  
  8.       return false;  
  9.   
  10.     return ProcessCommand(buffer, offset + sizeof(int) + commandLen, count - sizeof(int) - commandLen); //处理命令  
  11. }  

发包把UNICODE转为UTF-8

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

[csharp] view plain copy
  1. public bool DoSendResult()  
  2. {  
  3.     string commandText = m_outgoingDataAssembler.GetProtocolText();  
  4.     <span style="color:#ff6666;">byte[] bufferUTF8 = Encoding.UTF8.GetBytes(commandText);</span>  
  5.     int totalLength = sizeof(int) + bufferUTF8.Length; //获取总大小  
  6.     AsyncSendBufferManager asyncSendBufferManager = m_asyncSocketUserToken.SendBuffer;  
  7.     asyncSendBufferManager.StartPacket();  
  8.     asyncSendBufferManager.DynamicBufferManager.WriteInt(totalLength, false); //写入总大小  
  9.     asyncSendBufferManager.DynamicBufferManager.WriteInt(bufferUTF8.Length, false); //写入命令大小  
  10.     asyncSendBufferManager.DynamicBufferManager.WriteBuffer(bufferUTF8); //写入命令内容  
  11.     asyncSendBufferManager.EndPacket();  
  12.   
  13.     bool result = true;  
  14.     if (!m_sendAsync)  
  15.     {  
  16.         int packetOffset = 0;  
  17.         int packetCount = 0;  
  18.         if (asyncSendBufferManager.GetFirstPacket(ref packetOffset, ref packetCount))  
  19.         {  
  20.             m_sendAsync = true;  
  21.             result = m_asyncSocketServer.SendAsyncEvent(m_asyncSocketUserToken.ConnectSocket, m_asyncSocketUserToken.SendEventArgs,   
  22.                 asyncSendBufferManager.DynamicBufferManager.Buffer, packetOffset, packetCount);  
  23.         }                  
  24.     }  
  25.     return result;  
  26. }  

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

猜你喜欢

转载自blog.csdn.net/andrewniu/article/details/80234524