C#작은 endian 또는 big endian?
-
03-07-2019 - |
문제
에서 문서의 하드웨어를 제어할 수 있습을 통해 그것 UDP/IP, 내가 찾은 다음과 같은 조각:
이 통신 프로토콜,DWORD 는 4 바이트 데이터 워드는 2 바이트로 데이터 바이트는 하나의 바이트는 데이터입니다.저장 형식으로 작은 endian,즉 4 개의 바이트(32 비트)데이터로 저장됩니다:d7-d0,d15-d8,d23-d16,d31-d24;두 번 바이트(16 비트)데이터로 저장됩니다:d7-d0,d15-d8.
나이 어떻게 변환하는 C#?을 변환하기 전에 물건을 보내는 건가요?예를 들어,하고 싶은 경우에 보내 통해 32bit integer,또는 4 문자열?
해결책
C# 자체는 엔지니어를 정의하지 않습니다. 그러나 바이트로 변환 할 때마다 선택할 수 있습니다. 그만큼 비트 컨버터 클래스는 다음과 같습니다 Islittleendian 그것이 어떻게 행동 할 것인지 말해 주지만, 그것은 선택을 제공하지 않습니다. BinaryReader/BinaryWriter도 마찬가지입니다.
나의 오해 라이브러리에는 엔디 안 컨벤버 클래스가있어 엔디 언을 정의 할 수 있습니다. 바이너리 리더/라이터와 비슷한 등가물이 있습니다. 온라인 사용 안내서는 없지만 두려워하지만 사소합니다 :)
(EndianBitConverter는 또한 일반 비트 컨버터에 존재하지 않는 기능이 있습니다.이 기능은 바이트 어레이에서 전환하는 것입니다.)
다른 팁
당신은 또한 사용할 수 있습니다
IPAddress.NetworkToHostOrder(...)
짧고, int 또는 긴.
Little-Endian, 짧은 대답 (무엇이든해야 할 일)는 "아마도 그렇지는 않지만 하드웨어에 따라 다릅니다". 다음과 같이 확인할 수 있습니다.
bool le = BitConverter.IsLittleEndian;
이것이 말하는 것에 따라 버퍼의 일부를 뒤집을 수 있습니다. 또는 Jon Skeet에는 특정 엔디 언 변환기가 있습니다 여기 (EndianBitConverter를 찾으십시오).
이타늄 (예를 들어)은 빅 엔디언입니다. 대부분의 인텔은 리틀 엔디언입니다.
특정 UDP/IP ...?
에 대해 알아야 할 네트워크는 바이트 순서 뿐만 아니라 CPU endian-ness.
일반적으로 TCP/UDP 통신에,당신은 항상 데이터를 변환하여 네트워크를 바이트 사용하여 순서 htons
능(고 ntohs
, 고,관련 기능).
일반적으로 네트워크 order-endian 지만,이 경우에는 몇 가지 이유(!) 의 통신은 작은 endian,그래서 그 기능은 매우 유용되지 않습니다.이것은 중요한 것으로 가정할 수 없는 UDP 통신들은 구현에 따라 다른 어떤 표준,그것은 또한 어려운 생명이 있는 경우-endian 건축물을 포장과 함께 모든 것 htons
으로 해야 합니다:-(
그러나,당신이에서 오는 intel x86 아키텍처,그 당신은 이미 little-endian,그래서 그냥 보내지 않고 데이터 변환.
구문 분석하고 성능이 중요하지 않은 경우 매우 간단한 코드를 고려하십시오.
private static byte[] NetworkToHostOrder (byte[] array, int offset, int length)
{
return array.Skip (offset).Take (length).Reverse ().ToArray ();
}
int foo = BitConverter.ToInt64 (NetworkToHostOrder (queue, 14, 8), 0);
나는 주변의 재생과 함께 포장된 데이터에 UDP 멀티캐스트 및 나는 뭔가가 필요한 순서를 변경 UInt16 옥텟을 이후 오류가 나타났에서 패킷 헤더(Wireshark),그래서 나는 이것:
private UInt16 swapOctetsUInt16(UInt16 toSwap)
{
Int32 tmp = 0;
tmp = toSwap >> 8;
tmp = tmp | ((toSwap & 0xff) << 8);
return (UInt16) tmp;
}
의 경우에는 UInt32,
private UInt32 swapOctetsUInt32(UInt32 toSwap)
{
UInt32 tmp = 0;
tmp = toSwap >> 24;
tmp = tmp | ((toSwap & 0xff0000) >> 8);
tmp = tmp | ((toSwap & 0xff00) << 8);
tmp = tmp | ((toSwap & 0xff) << 24);
return tmp;
}
이것은 단지에 대한 테스트
private void testSwap() {
UInt16 tmp1 = 0x0a0b;
UInt32 tmp2 = 0x0a0b0c0d;
SoapHexBinary shb1 = new SoapHexBinary(BitConverter.GetBytes(tmp1));
SoapHexBinary shb2 = new SoapHexBinary(BitConverter.GetBytes(swapOctetsUInt16(tmp1)));
Debug.WriteLine("{0}", shb1.ToString());
Debug.WriteLine("{0}", shb2.ToString());
SoapHexBinary shb3 = new SoapHexBinary(BitConverter.GetBytes(tmp2));
SoapHexBinary shb4 = new SoapHexBinary(BitConverter.GetBytes(swapOctetsUInt32(tmp2)));
Debug.WriteLine("{0}", shb3.ToString());
Debug.WriteLine("{0}", shb4.ToString());
}
에서는 출력이 있었다:
0B0A: {0}
0A0B: {0}
0D0C0B0A: {0}
0A0B0C0D: {0}