Send Structure over network as Byte()

sgt_pinky

Well-known member
Joined
Jan 5, 2005
Messages
80
Location
Melbourne, Australia
Hi,

I have been making a game that uses TCP and UDP. For the UDP part it sends information such as player location, bullet information, and particle effects. I am having problems working out the best way to send the information over UDP.

At the moment I am using the following 2 functions to convert a Structure to a Byte(), and vice versa.

Code:
    Public Function StructToBytes(ByVal InStruct As Object) As Byte()
        Dim Ptr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(InStruct))
        Dim ByteArray(Marshal.SizeOf(InStruct) - 1) As Byte
        Marshal.StructureToPtr(InStruct, Ptr, False)
        Marshal.Copy(Ptr, ByteArray, 0, Marshal.SizeOf(InStruct))
        Marshal.FreeHGlobal(Ptr)
        Return ByteArray
    End Function

and,

Code:
    Public Function BytesToStruct(ByVal Buff() As Byte, ByVal MyType As System.Type) As Object
        Dim MyGC As GCHandle = GCHandle.Alloc(Buff, GCHandleType.Pinned)
        Dim Obj As Object = Marshal.PtrToStructure(MyGC.AddrOfPinnedObject, MyType)
        MyGC.Free()
        Return Obj
    End Function

The problem is that ideally I want to have several different types of structure. Eg, a Structure that is only for updating a players position, or a Structure only for a particle effect. At the moment I only have one big structure, will all information in it, because I have to convert the structure at the other end, so I always know what type it is. If I have more than one type of structure, then I dont know the Type at the other end to convert it back from a byte array.

Looking for some ideas if you have any. I was thinking of somehow using an Enum to specify the type of the structure, but not too sure.

Cheers,

Pinky
 
Rather than rely on GC handles and a lot of interop code why dont you just serialize to a byte array?
Code:
For a structure
<Serializable()> _
Structure SampleStruct
    Public i As Integer
    Public s As String
    etc.
End Structure

the following should work...

Dim ms As New IO.MemoryStream()
Dim s As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()

any old sample structure / data
Dim test As SampleStruct
test.i = 1000
test.s = "Hello World"

s.Serialize(ms, test)

following just removes any padding as allocated by ms
Dim b(ms.Position) As Byte
Array.Copy(ms.GetBuffer, b, ms.Position)
b() now contains a serialized version of test
ms.Close()

If you are using something like this then just declare an enum of all posible structure types and send that as the first byte / integer of the packet and deserialize the correct structure based on its value at the other end.
 
Back
Top