Путаница в htons- little endian / big endian

Asked
Viewd11347

9

Когда я отправляю целочисленную переменную из одного процесса в другой через сокет, а затем печатаю значение на полученном конце, значение остается прежним без использования ntohl / htonl, тогда где мне нужно использовать эти функции, кроме инициализациирозеточные конструкции.Я понимаю little / big endian.Но зачем нам преобразовывать номера портов и IP в порядок байтов хоста / сети, когда значение остается прежним.Пожалуйста, объясните подробно, как целое число передается по сети?

3 ответов

16

Если вы хотите, чтобы ваша программа была переносимой, то каждый раз, когда вы отправляете целое число размером более 1 байта по сети, вы должны сначала преобразовать его в сетевой порядок байтов, используя htons или htonl, а принимающий компьютер должен преобразовать его.для размещения порядка байтов с использованием ntohs или ntohl.

В вашем случае причина того, что значение остается прежним, вероятно, заключается в том, что передающий компьютер и принимающий компьютер имеют одинаковую последовательность байтов.Другими словами, и передающий, и принимающий компьютеры, с которыми вы работаете, имеют прямой порядок байтов (или большой порядок байтов в любом случае).

Но если вы хотите, чтобы ваша программа была переносимой, вы не можете рассчитывать, что так будет всегда.Однажды, например, отправляющий компьютер может быть Intel x86, а получающий - Sun SPARC, и тогда ваша программа выйдет из строя, если вы не используете htons.

  • Члены структуры @AndrewMcKinlay упорядочены в том порядке, в котором они были определены.Однако есть и другие проблемы, такие как заполнение: http://stackoverflow.com/a/2749096/4131237

    Prashanth Chandra11 сентября 2016, 04:13
  • А как насчет нецелочисленных типов данных, таких как структуры?Есть ли у них порядок байтов?

    Andrew McKinlay24 февраля 2014, 05:13
  • Я написал клиент и сервер и не использовал htonl и ntohl.Скажем, когда я отправил 6, сервер получил 6 значений.Тогда зачем нужны эти функции?

    avd05 ноября 2009, 05:23
  • Я не согласен со всем первым абзацем.Сериализация и десериализация возможны без hton* и ntoh*, и на самом деле эти функции не гарантируют выполнение сериализации.

    autistic30 января 2017, 06:55
  • Эти функции необходимы в том случае, если клиент работает на компьютере с прямым порядком байтов, а сервер - на компьютере с прямым порядком байтов, или наоборот.

    Charles Salvia05 ноября 2009, 05:26
0

Он остается таким же, потому что в вашей архитектуре сетевой порядок такой же, как и собственный порядок.Если вы никогда не собираетесь компилировать свой код для другой архитектуры, вы можете опустить вызовы hton / ntoh.Тогда ваш код не будет переносимым.

  • Вы правы - я хотел сказать что-то в этом роде, но не очень ясно ответил.

    Jim Garrison05 ноября 2009, 16:03
  • Это неверно.Он вполне мог использовать архитектуру, в которой порядок хостов отличается от порядка в сети.Ваш код будет «работать» без htonX / ntohX всякий раз, когда архитектура обеих конечных точек имеет одинаковый порядок байтов.

    R Samuel Klatchko05 ноября 2009, 06:39
9

Если вы хотите отправить данные с машины x86 или amd64 на машину с процессором PowerPC, в двоичном формате вы быстро увидите, что ваши данные сталкиваются с "проблемой NUXI", так как разныепроцессоры по-разному обрабатывают целые числа и, кажется, меняют байты местами.(На самом деле они не меняют местами байты - они просто работают с ними в другом порядке.)

При работе на x86 или amd64 младший байт занимает первое место в памяти (таким образом вы можете выполнять сложение от младших адресов к старшим).PowerPC помещает наиболее значимый байт в память первым (таким образом вы можете сортировать числа на основе байтов, которые поступают в память раньше - строковая и целочисленная сортировки могут быть совершенно одинаковыми).