使用C#實現Python struct.pack 和unpack函數


使用C#來模擬python pack和unpack函數的效果的需求來自一次作業,作業做一個聯網的射擊游戲,那么不可避免地要進行服務端和客戶端地交互,但是服務端代碼由Python編寫,而客戶端代碼由C#完成,並且服務端發送數據又經過pack打包,這樣一來,客戶端就需要去解析收到的數據,然而沒有對應的庫或者函數可以用(又或者我沒有找到),所以我根據我的使用場景來實現了打包和解包的函數。本來不打算發出來,因為沒有經過嚴格的測試(又或者說只適用於我這里的問題),但如果你也有類似的問題,不妨看一看,可能會有啟發。

我的使用場景:

 服務端向客戶端發送數據時,使用包頭+data的方式來避免粘包。首先把計算數據和包頭長度,而后將其pack成字符串,與data組合一並發送至客戶端,由客戶端進行解析。

pack format:4 bytes little endian (x86) by default

 我觀察打印的的結果后,實現了c#端的對應打包解包函數如下:

C# - pack (pack之后是一個16進制串,需要把一個整數轉換成一個4字節小端,即低位存儲在低字節的16進制字符串

 1     /// <summary>
 2     /// format the dec integer to a hex stream, for sending msg 
 3     /// </summary>
 4     /// <param name="size"> dec integer </param>
 5     /// <returns> hex stream </returns>
 6     public string Dec2HexStream(int size)
 7     {
 8 
 9         string raw = "00000000";
10         string hex = Convert.ToString(size, 16);
11         //Console.WriteLine("轉換字符串 " + hex + " 長度 " + hex.Length);
12         int hexLen = hex.Length;
13         if (hexLen > 8)
14             return "\x00\x00\x00\x00";
15         else
16         {
17             // 100 -> 00 01 00 00 -> 00 00 01 00
18             hex = raw.Substring(0, 8 - hexLen) + hex;
19         }
20         //Console.WriteLine("加0字符串 " + hex);
21 
22         string res = "";
23         for (int i = 3; i >= 0; i--)
24         {
25             res += hex.Substring(i * 2, 2);
26         }
27         hex = res;
28 
29         //Console.WriteLine("反轉字符串 " + hex);
30         res = "";
31         for (int i = 0; i < 4; i++)
32         {
33             res += "\\x" + hex.Substring(i * 2, 2);
34         }
35         //Console.WriteLine("結果字符串 " + res);
36         return Regex.Unescape(res);
37     }

 

C# - unpack (對應的將4字節小端存儲的16進制字符串轉換成為一個整數

 1     /// <summary>
 2     /// for recving msg and parsering the size of data
 3     /// </summary>
 4     /// <param name="s"> hex stream </param>
 5     /// <returns>dec integer</returns>
 6     public int HexStream2Dec(string s)
 7     {
 8         // 00 01 00 00
 9         // 00 00 01 00 
10         // \x01\x00\x00\x00 小端
11         UInt32 res = 0;
12         //Console.WriteLine("處理字符串 " + s);
13         string tmp = "";
14         for (int i = 3; i >= 0; i--)
15         {
16             UInt32 m = Convert.ToUInt32(s[i]);
17             string hexs = Convert.ToString(m, 16);
18             tmp += hexs;
19         }
20         //Console.WriteLine("還原字符串 " + tmp + " 長度 " + (tmp.Length).ToString());
21         res = Convert.ToUInt32(tmp, 16);
22         return (int)res;
23     }

本文首發、修改於 博客園 yocichen

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM