【问题标题】:How should a C# struct be sent over the network to a C++ client?应该如何通过网络将 C# 结构发送到 C++ 客户端?
【发布时间】:2023-04-08 17:45:01
【问题描述】:

我在获取通过 TCP 套接字发送到 C++ 客户端以正确读取的 C# 结构字节时遇到了一些问题。这是结构...

C# 中的结构

public struct TankBattleStateData
{
    public int playerID;
    public float currentHealth;

    public Vector3 position;
    public Vector3 forward;

    public Vector3 cannonForward;

    public int canFire;
    public int tacticalCount; 
}

C++ 中的结构

struct TankBattleStateData
{
    int playerID;
    float currentHealth;

    float position[3];
    float forward[3];

    float cannonForward[3];

    int canFire;
    int tacticalCount;
};

传输过程如下...

  1. 使用System.Runtime.InteropServices.Marshal 获取表示结构的C# 字节数组
  2. 将字节数组输入 Socket.Send 以发送到 C++ 客户端
  3. 客户端在收到字节后,将对收到的字节进行 memcpy 到堆上的 unsigned char 数组,如果需要,在复制之前调整大小
    • 有一些检查,例如验证读取的字节数,但没有什么特别强大的地方。
  4. 为了读取其内容,客户端将指向 char 数组的指针转换为 TankBattleStateData * 并取消引用以访问其字段。

我始终发现,最后一个字段tacticalCount 在 C++ 客户端上的值与在 C# 客户端上的值不同。例如,我将从服务器发送1,然后在客户端返回81742424

环境

操作系统:Windows 10 x64
服务器:带有 .NET Framework 2.0 的 C# (Unity3D 5.3.2f1)
客户端:带 MSVC++14 的 C++

我想知道的

  1. 我做错了什么? ;)
    • 更具体地说,我在客户端上做错了什么?我设置了一个 C# 客户端,它接收数据似乎没有问题,不像 C++ 客户端。
  2. 是否有现有的库可以让我的生活更轻松?

我遇到的一个问题是 C# bool 被编组为 4 bytes,而不是 1 字节,这是 MSVC++14 中布尔值的大小。我想使用bool,但为了减少可能出现的问题,我现在使用int

【问题讨论】:

  • 你的 C++ ints 有多大?你确定它们不是 16 位的吗?
  • 关于 (2),您可以查看像 Google Protocol Buffers 或 MessagePack 这样的二进制序列化库,以独立于平台的方式为您执行此操作。
  • @SLaks 虽然我的问题已经解决,但根据sizeof(int),我的 C++ ints 是 4 字节,所以这让我相信它们是 32 位的。 (再次感谢!)

标签: c# c++ network-programming marshalling


【解决方案1】:

[StructLayout(LayoutKind.Sequential)] 添加到结构中,然后使用[FieldOffset] 对字段进行布局以完全匹配C++ 版本。

【讨论】:

  • 看来我只能使用one or the other。使用它们都会导致错误声明,The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit). 编辑:抱歉,没有意识到按 ENTER 会提交我的评论。还没有完全完成编写或测试这两者。给我一秒钟...
  • @terrehbyte:你是对的;我的意思是Explicit。 (除非Sequential 匹配,在这种情况下你可以使用它)
【解决方案2】:

您应该阅读的是数据结构的序列化和反序列化。有多种协议、库和方法可用。将原始数据发送到内存或从内存发送数据可能会对字节序、文本字段和数组产生奇怪的影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    相关资源
    最近更新 更多