C # Convert from byte [] to structure. Byte order is incorrect

I tried to use a structure to analyze socket data when implementing a protocol based on UDP. And I searched, and I can use these 2 functions to convert between byte [] and struct:

byte[] StructToBytes(object structObj) { int size = Marshal.SizeOf(structObj); IntPtr buffer = Marshal.AllocHGlobal(size); try { Marshal.StructureToPtr(structObj, buffer, false); byte[] bytes = new byte[size]; Marshal.Copy(buffer, bytes, 0, size); return bytes; } finally { Marshal.FreeHGlobal(buffer); } } static object BytesToStruct(byte[] bytes, Type strcutType, int offset = 0) { int size = Marshal.SizeOf(strcutType); IntPtr buffer = Marshal.AllocHGlobal(size); try { Marshal.Copy(bytes, offset, buffer, size); return Marshal.PtrToStructure(buffer, strcutType); } finally { Marshal.FreeHGlobal(buffer); } } 

Then I had this problem:

 //I defined a simple struct with an ushort member [StructLayout(LayoutKind.Sequential, Pack = 2)] struct S { public ushort a; } //Then I define a byte[] byte[] bArr; bArr[0] = 0; bArr[1] = 1; //Convert to struct S s = (S)BytesToStruct(bArr, typeof(S)); //Then sa = 0x0100 not 0x0001 

And struct to byte [] is the same. 2 ushort bytes canceled. How to solve this problem?

+4
source share
3 answers

Most processors today use the Little-Endian byte order (the low byte begins first). Network byte ordering is a traditional Big-Endian, so you usually need to mirror the byte order. You can check the consistency of the system using System.BitConverter.IsLittleEndian

.NET equivalent of ntohs () Frank is mentioned (weird) in System.Net.IPAddress.NetworkToHostOrder()

You can also write your own mechanism for directly reading bytes in the correct order using bit shift and logical OR.

+2
source

There is a difference between the network byte order and the host byte order.

Typically, in C, at least you use ntohl (), ntohs (), and friends to convert network byte order to your host code when reading from a socket.

+1
source

The problem is that there is a short conformation on your system. Look at this endianness question , which may contain some pointers (pun intended).

In addition, I would suggest creating a BytesToStruct generic in a struct type:

 static S BytesToStruct<S>(byte[] bytes, int offset = 0) 

so that it can be called with

 BytesToStruct<S>(bArr) 

not like now

 (S)BytesToStruct(bArr, typeof(S)) 
+1
source

All Articles