Неразбериха в htons- младший / большой порядок
Когда я посылаю целочисленную переменную из одного процесса в другой через сокет, а затем печатаю значение на полученном конце, значение остается тем же без использования ntohl/htonl, тогда где мне нужно использовать эти функции, кроме инициализации структур сокетов. Я понимаю Литт / Big Endian. Но зачем нам нужно преобразовывать номера портов и IP-адресов в порядок байтов хоста / сети, если значение остается прежним. Пожалуйста, объясните подробно, как целое число передается по сети?
3 ответа
Если вы хотите, чтобы ваша программа была переносимой, то каждый раз, когда вы отправляете целое число больше 1 байта по сети, вы должны сначала преобразовать ее в сетевой порядок байтов, используя htons
или же htonl
и принимающий компьютер должен преобразовать его в порядок байтов хоста, используя ntohs
или же ntohl
,
В вашем случае причина, по которой значение все равно, вероятно, заключается в том, что отправляющий и принимающий компьютеры имеют одинаковый порядок байтов. Другими словами, отправляющий компьютер и принимающий компьютер, с которым вы работаете, имеют младший (или большой, в любом случае).
Но если вы хотите, чтобы ваша программа была переносимой, вы не можете полагаться на это всегда. Например, однажды отправляющий компьютер может быть Intel x86, а принимающим может быть Sun SPARC, и тогда ваша программа не будет работать, если вы не используете htons
,
Если вы хотите отправить данные с компьютера x86 или amd64 на компьютер с процессором PowerPC, в двоичном формате вы быстро увидите, что ваши данные сталкиваются с "проблемой NUXI", поскольку разные процессоры по-разному обрабатывают целые числа и, по-видимому, меняют местами байт. (На самом деле они не меняют местами байты - они просто работают с ними в другом порядке.)
При работе на x86 или amd64 младший значащий байт занимает первое место в памяти (таким образом, вы можете выполнять добавление от младшего к старшему адресу памяти). PowerPC помещает самый старший байт первым в память (таким образом, вы можете сортировать числа на основе байтов, которые находятся раньше в памяти - сортировка строк и целочисленная сортировка могут быть абсолютно одинаковыми).
Это остается тем же, потому что в вашей архитектуре сетевой порядок такой же, как и у нативного. Если вы никогда не ожидаете компиляции своего кода для другой архитектуры, вы можете пропустить вызовы hton/ntoh. Ваш код не будет переносимым.