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-символьную строку?

231   6  

6 ответов:

сам C# не определяет конечность. Однако всякий раз, когда вы конвертируете в байты, вы делаете выбор. Элемент BitConverter классе IsLittleEndian поле, чтобы сказать вам, как он будет себя вести, но это не дает выбора. То же самое касается BinaryReader/BinaryWriter.

мой MiscUtil библиотека имеет класс EndianBitConverter, который позволяет определить endianness; существуют аналогичные эквиваленты для BinaryReader/Writer. Нет руководство по использованию в Интернете я боюсь, но они тривиальны:)

(EndianBitConverter также имеет часть функциональности, которая не присутствует в обычном BitConverter, который должен делать преобразования на месте в массиве байтов.)

вы также можете использовать

IPAddress.NetworkToHostOrder(...)

для short, int или long.

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}
    Ничего не найдено.

Добавить ответ:
Отменить.