C# little endian или big endian?
в документации оборудования, что позволяет нам управлять им через UDP/IP и,
Я нашел следующий фрагмент:
в этом протоколе связи DWORD-это 4 байта данных, WORD - это 2 байта данных,
Байт-это однобайтовые данные. Формат хранения мало endian, а именно 4 байта (32bits) данные хранятся как: d7-d0, d15-d8, d23-d16, d31-d24; двойные байты (16bits) данные хранятся как: d7-d0 , d15-d8.
Мне интересно, как это переводится на C#?
Делать Я должен конвертировать вещи перед отправкой?
Например, если я хочу отправить 32-битное целое число или 4-символьную строку?
6 ответов:
сам C# не определяет конечность. Однако всякий раз, когда вы конвертируете в байты, вы делаете выбор. Элемент BitConverter классе IsLittleEndian поле, чтобы сказать вам, как он будет себя вести, но это не дает выбора. То же самое касается BinaryReader/BinaryWriter.
мой MiscUtil библиотека имеет класс EndianBitConverter, который позволяет определить endianness; существуют аналогичные эквиваленты для BinaryReader/Writer. Нет руководство по использованию в Интернете я боюсь, но они тривиальны:)
(EndianBitConverter также имеет часть функциональности, которая не присутствует в обычном BitConverter, который должен делать преобразования на месте в массиве байтов.)
Re little-endian, короткий ответ (мне нужно что-то делать) - "вероятно, нет, но это зависит от вашего оборудования". Вы можете проверить с помощью:
bool le = BitConverter.IsLittleEndian;в зависимости от того, что это говорит, Вы можете поменять местами части ваших буферов. Кроме того, у Джона Скита есть специальные преобразователи-endian здесь (ищите EndianBitConverter).
обратите внимание, что itaniums (например) являются big-endian. Большинство Интелс являются прямым порядком байтов.
Re специфический UDP / IP...?
вы должны знать о порядке байтов сети, а также о конце процессора.
обычно для связи TCP / UDP вы всегда преобразуете данные в сетевой порядок байтов с помощью
htons
Если вы анализируете и производительность не критична, рассмотрим этот очень простой код:
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 Multicast, и мне нужно было что-то переупорядочить октеты 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}
Comments