🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

fill fixed byte with values

Started by
7 comments, last by rogerdv 4 years, 9 months ago

Im doing some tests with new Unity3d networking APi and Im moving from sending integers to sending more complex stuff, like coordinates (3 floats). The problem is that Im forced to use fixed byte as the data container for my packets (byte[] doesnt works, must be unmanaged and blittable) and I havent found a way to put my values (floats, strings, etc) into that array of bytes and also get them back. How can I do this?

Advertisement

I don't know the answer, as I'm not up to date with Unity and am not sure what features are available there.

I did find a couple threads that might (or might not) be relevant (the information may be out of date though - the threads are a few years old):

1
2

Also, it sounds like you've already figured out how to serialize integers (which I assume doesn't mean only bytes). How are you doing that? It seems like the solution for other types (e.g. floats) could be related.

In regular C# BitConverter is what you're looking for, I don't know if it's available in Unity though:

 

https://docs.microsoft.com/de-de/dotnet/api/system.bitconverter?view=netframework-4.8

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

You do 'fixed' stuff like you do in C; LIKE A BOSS.


public unsafe void Foo()
{
    byte[] array = new byte[1024]; // for example; I assume you get your byte* from elsewhere.

    fixed (byte* ptr = array)
    {
        int* i = (int*)ptr; // cast pointer types to whatever you want
        // ^ you see that BLASPHEMY with the asterisk associated with the int?
        // That's different than C: int *i

        *i = 0x12345678;

        // moving the pointer works the same as C - advancing by the data type's size.
        // if you want to mix types, keep a byte* around to position things correctly.
        i++;

        *i = 0x23456789;

        // getting things back out is the same.
        int value = *i;  // value is now 0x23456789
        --i;
        int value2 = *i; // value2 becomes 0x12345678
    }

    // array is now 78 56 34 12 89 67 45 23 00 00 00 ......
}

You can also use the Marshal class to be (slightly) less of a BOSS.

Involving unsafe what is your necesity quoting

On 9/17/2019 at 7:25 PM, rogerdv said:

(byte[] doesnt works, must be unmanaged and blittable)

It will cut out the entire memory outside of Garbace Colector (the GC) untill you return it under management, you would better copy the memory as advised with Bit Converter and "unsafe" the copy to unmanaged modules, then you are set good smooth.

On 9/17/2019 at 5:00 PM, Zakwayda said:

I don't know the answer, as I'm not up to date with Unity and am not sure what features are available there.

I did find a couple threads that might (or might not) be relevant (the information may be out of date though - the threads are a few years old):

1
2

Also, it sounds like you've already figured out how to serialize integers (which I assume doesn't mean only bytes). How are you doing that? It seems like the solution for other types (e.g. floats) could be related.

By using DataStreamWriter, it can write ints or floats. The thing gets complicated when I want to write a series of floats, or an int+float+float+float, etc, to build an useful data packet.

17 hours ago, Endurion said:

In regular C# BitConverter is what you're looking for, I don't know if it's available in Unity though:

 

https://docs.microsoft.com/de-de/dotnet/api/system.bitconverter?view=netframework-4.8

It is, but it is not compatible with fixed byte.

3 minutes ago, rogerdv said:

By using DataStreamWriter, it can write ints or floats. The thing gets complicated when I want to write a series of floats, or an int+float+float+float, etc, to build an useful data packet.

Apologies if I'm missing the obvious, but can you just write and read the ints/floats/etc. in sequence? (One of the threads I linked to suggests serializing vectors in this way.)

Ok, as I expected, I had to change my design. The problem came mostly from the fact that the gae uses  new Unity threading system. I wanted to send a list of possible commands from my main thread on each Update() iteration, to the thread sending and receiving network data. That required using a NativeList or a NativeArray of the commands struct, which I wanted to contain the command code, length and the actual packet data. Also, the network thread should return a similar list of commands received from the server. Seems it is impossible, or my knowledge is not enough to do it. I had to change my approach to send only one command per frame. So, I can build the packet data inside a byte[] and copy it to a NativeArray<byte>, which I pass separately to the network thread (it is done that way in the Unity sample, though they simply fill the byte[] array with random values).

The other solution was to change the client architecture from multithreaded to single threaded, but as anyway I must code the server as multithreaded, I would face the problem eventually anyway. Thanks to all of you for your invaluable help!

This topic is closed to new replies.

Advertisement