2010-08-16 2 views
4

UDP 기반 프로토콜을 구현할 때 소켓 데이터를 구문 분석하기 위해 구조체를 사용하려고했습니다. 가 내가 검색 한 내가 바이트 []와 구조체 사이의 변환이이 개 기능을 사용할 수 있습니다 C# byte []에서 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); 
     } 
    } 

그런 다음 나는이 문제를 가지고 : 그냥 같은 [] 바이트

//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 s.a = 0x0100 not 0x0001 

그리고 구조체이다 . ushort의 2 바이트가 반대로됩니다. 이 문제를 어떻게 해결합니까?

답변

2

요즘 대부분의 프로세서는 리틀 엔디 언 바이트 순서 (least significant byte first)를 사용합니다. 네트워크 바이트 순서는 전통적인 Big-Endian이므로 일반적으로 바이트 순서를 미러링해야합니다. 당신은 또한 올바른 순서로 바이트를 읽고 자신의 메커니즘을 쓸 수 System.Net.IPAddress.NetworkToHostOrder()

에서 System.BitConverter.IsLittleEndian

와 프랭크 (이상한)의 매력에 빠져 언급() ntohs의 닷넷 상응하는 시스템의 엔디안을 확인하실 수 있습니다 직접 비트 시프 팅 및 논리 OR을 사용합니다.

1

네트워크 바이트 순서와 호스트 바이트 순서간에 차이가 있습니다.

일반적으로 최소한 C에서는 소켓에서 읽을 때 ntohl(), ntohs() 및 friends를 사용하여 네트워크 바이트 순서를 호스트 순서로 변환합니다.

1

문제점은 시스템에서 endianness가 short 인 것과 관련이 있습니다. this question about endianness을보십시오. 일부 포인터 (의도하지 않은 말장난)를 제공 할 수 있습니다.

또한, 나는 struct의 유형에서 일반적인 BytesToStruct 만들기 제안 : 그래서

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

그것을 오히려 현재

(S)BytesToStruct(bArr, typeof(S)) 
에서와 같은보다

BytesToStruct<S>(bArr) 

호출 할 수

관련 문제