简体   繁体   English

如何封送包含大小可变的字符串的结构?

[英]How can I marshal a struct containing strings of variable size?

I'm sending stuff over a TCP connection from the client to my server in a packet ( MemoryStream ), and on the server end I want to re-create the original object by using the Marshal. 我正在通过TCP连接从客户端以数据包( MemoryStream )的方式向服务器发送内容,并且在服务器端,我想使用元帅来重新创建原始对象。 I'm using the following code to marshal stuff into the packets: 我正在使用以下代码将数据封送入数据包:

    public void Write<T>(T value) where T : struct
    {
        byte[] buffer = new byte[Marshal.SizeOf(typeof(T))];

        // Fill the buffer with our stuff please!
        fixed (byte* b = buffer)
            Marshal.StructureToPtr(value, new IntPtr(b), false);

        // And write it to the MemoryStream. Kthx!
        Write(buffer, 0, buffer.Length);
    }

When I'm done writing stuff to the packet I call ToArray() on it and send it over to the server. 当我写完数据包后,我在其上调用ToArray()并将其发送到服务器。 The server will then receive a byte array with all the data in it. 然后,服务器将接收一个包含所有数据的字节数组。

And this works fine for all primitive types, but it doesn't work too well for my custom structs. 这对于所有原始类型都适用,但是对于我的自定义结构而言效果并不理想。 Consider the following struct I'm using: 考虑以下我正在使用的结构:

[StructLayout(LayoutKind.Sequential)]
public struct HotspotUpdate
{
    public string LeaderHash { get; set; }
    public string OurName { get; set; }
    public CommandSide Side { get; set; }
    public CommandType Type { get; set; }
    public Vector3 Location { get; set; }
}

I usually make these structs work by specifying the Size in the StructLayout attribute. 我通常通过在StructLayout属性中指定Size来使这些结构起作用。 However, now I have two strings in there of varying size, and I can't for the life of me figure out how I can get the Marshal to grab a packet (which is a byte array) and have it marshal it back to the above struct since I can't specify it as an LPStr and set its size - it will vary. 但是,现在我有两个大小不一的字符串,而且我一生都无法弄清楚如何让Marshal来抓包(是字节数组)并将其编组回上面的结构,因为我无法将其指定为LPStr并设置其大小-它会有所不同。

So whenever I do attempt this, the marshal will yell at me, saying: 因此,无论何时我尝试这样做,元帅都会对我大喊:

Type 'HotspotUpdate' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.

Is there any way I can make this work, or will I have to resort to just sending over strings a byte arrays and working them out on the server end? 有什么方法可以使这项工作有效,还是我不得不诉诸于仅通过字符串发送字节数组并在服务器端对其进行处理?

The CLR demands that struct members are located at fixed offsets. CLR要求结构成员位于固定的偏移量。 Therefore, there are no variably-sized members. 因此,没有大小可变的成员。

Probably, you should use a higher level of abstraction anyway. 可能无论如何,您应该使用更高级别的抽象。 Use protocol buffers to automate all your serialization needs in a convenient and robust way. 使用协议缓冲区以方便且健壮的方式自动执行所有序列化需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM