Хорошо, кажется, есть проблемы с тем, что вы делаете на двух разных уровнях. Здесь, кажется, частично возникает путаница из-за использования вами указателей, типа объектов, на которые они указывают, а затем интерпретации кодирования значений в памяти, на которые указывают указатель (и).
Кодирование многобайтовых объектов в памяти - это то, что называется порядком байтов. Две общие кодировки называются Little Endian (LE) и Big Endian (BE). В LE 16-разрядная величина, такая как короткое замыкание, сначала кодируется младшим значащим байтом (LSB). Под BE самый старший байт (MSB) кодируется первым.
По соглашению сетевые протоколы обычно кодируют вещи в то, что мы называем «сетевым порядком байтов» (NBO), которое также совпадает с BE. Если вы отправляете и получаете буферы памяти на платформах с прямым порядком байтов, вы не столкнетесь с проблемами преобразования. Однако ваш код будет зависеть от платформы в соответствии с соглашением BE. Если вы хотите написать переносимый код, который работает корректно как на платформах LE, так и на платформе BE, вы не должны предполагать, что платформа является инициатором.
Достижение переносимости в порядке байтов является целью таких процедур, как ntohs () , ntohl () , htons () и htonl () . Эти функции / макросы определены на данной платформе для выполнения необходимых преобразований на отправляющей и принимающей сторонах:
- htons () - преобразовать короткое значение из заказа хоста в сетевой заказ (для отправки)
- htonl () - преобразовать длинное значение из заказа хоста в сетевой заказ (для отправки)
- ntohs () - преобразовать короткое значение из сетевого заказа в заказ хоста (после получения)
- ntohl () - преобразовать длинное значение из сетевого заказа в заказ хоста (после получения)
Поймите, что ваш комментарий о доступе к памяти при приведении к символам не влияет на фактический порядок объектов в памяти. То есть, если вы обращаетесь к буферу в виде последовательности байтов, вы увидите байты в том порядке, в котором они фактически были закодированы в памяти, независимо от того, есть ли у вас машина BE или LE. Так что, если вы смотрите на буфер, закодированный NBO после получения, MSB будет первым - всегда. Если вы посмотрите на выходной буфер после того, как вы преобразовали обратно в порядок хостов, если у вас есть машина BE, порядок байтов не изменится. И наоборот, на компьютере LE все байты теперь будут инвертированы в преобразованном буфере.
Наконец, в цикле преобразования переменная total
ссылается на байты. Однако вы обращаетесь к буферу как shorts
. Ваша защита от петель не должна быть total
, но должна быть:
total / sizeof( unsigned short )
для учета двухбайтовой природы каждого short
.