• 使用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 "x00x00x00x00";
    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         // x01x00x00x00 小端
    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

  • 相关阅读:
    linux 环境变量恢复默认值
    怎么查看Eclipse的版本信息
    掌握HDFS的Java API接口访问
    【代理】代理概念
    【DbUtils】轻量级的ORM学习
    【mysql】相关记录
    JWT(JSON Web Tokens)
    将jar包安装到本地仓库
    Spring集成rabbitmq
    spring-rabbit包的引入需要注意的事项
  • 原文地址:https://www.cnblogs.com/yocichen/p/13167673.html
Copyright © 2020-2023  润新知