2017-01-07 7 views
1

Я прочитал this explanation и this manual page об использовании htons, htonl, ntohl и ntohs, однако я до сих пор не в полной мере понять их использование (я совершенно новой для сокета API и сетевого программирования в целом) , Я понимаю маленький и большой порядок Endian и byte, но я не уверен, как правильно реализовать эти функции в моем коде приложения чата, поэтому он работает последовательно на разных компьютерах (где используется большой Endian, а другой мало используется).Решают между htons и Htonl

Небольшой контекст для моей конкретной ситуации; У меня есть (почти) полностью работающее приложение для чата, и я только что использовал htons, но после некоторых исследований кажется, что это ненадежно. Я понимаю, что this question может показаться довольно похожим, однако здесь я спрашиваю о примере реализации, я уже знаю основную функцию этих вызовов.

+0

* «но после некоторых исследований кажется, что это ненадежно» * Не уверен, что вы подразумеваете под этим. Пожалуйста, объясни. – user3386109

+0

Я не имею в виду, что функция ненадежна, я имею в виду, что если я не использую правильную функцию, моя программа может отправлять неожиданные данные (неправильный порядок байтов). Пожалуйста, исправьте меня, если я ошибаюсь, но по первой ссылке, которую я предоставил, он сказал следующее: * «В результате это означает, что если вы отправляете() двухбайтный короткий int из коробки Intel на Mac (до того, как они стали Ящики Intel тоже, я имею в виду), то, что один компьютер считает номером 1, другой будет считать число 256, и наоборот.* " – carefulnow1

+2

Когда вы собираетесь * отправлять * данные со своего хоста по сети, вы готовите его с помощью hton *. Когда вы получаете данные из своего хоста из сети, вы используете ntoh *. Вы выбираете версию' s', если данные находятся в 'коротком' (или, точнее,' int16_t') и 'l' варианте, если это' long'. Что насчет этого сбивает с толку? – rici

ответ

1

Идея имеет некоторое общее представление для целых типов. TCP/IP использует NBO, порядок байтов в сети. И что бы это ни было (большой или маленький конец или более экзотический), способ отправить 16-битное целое число или 32 бита - использовать htons или htonl перед отправкой таких данных. Тогда при получении вы должны преобразовать его обратно в представлении хоста с ntohs и ntohl:

Отправитель хотите отправить значение uint32_t a, то он посылает данные, возвращаемые htonl(a), скажем, d.

Получатель получает d, применяет ntohl(d) и получает правильное значение uint32_t.

Тезисы только кодирование/декодирование функции. Отправитель отправляет код (v), затем приемник получает декодирование (код (v))! Вам не нужно знать, какой код (v) равен (без процентов).

Если это кажется вам ненадежным, это связано с тем, что вы не используете его так, как должно быть.

+0

Я действительно понимаю эту часть, но почему некоторые пользователи говорят, что я должен использовать ее при хранении номера порта в моей серверной структуре? Насколько я вижу, он не отправлен нигде, единственное, что было отправлено, это массив символов, содержащий сообщение ... – carefulnow1

+0

Что вы назвали * server struct *? Помните, что при отправке сообщения есть много информации, в которой хранятся ваши данные, информация об отправителе ip, информация об ip-адресах приемника и т. Д. Поэтому есть необходимость дать им точный порядок байтов. –

+0

А так, когда клиент выполняет запись (носок, сообщение, strlen (сообщение)), он также отправляет некоторые данные, такие как server.sin_port? – carefulnow1

0

Если вы отправляете данные в сети между двумя компьютерами, приемник должен интерпретировать данные так, чтобы значение интерпретации было таким же, как и значение отправителя.

Предположим, что отправитель отправляет LONG из 4 байтов на сетевом компьютере с маленькой конечной машины, а машина ресивера - большой. В этом случае приемник может интерпретировать 4 байта в другом порядке.

Функции HtoNx и NtoHx помогают сделать передачу однородной, учитывая, что сеть является большой энтикой. Для каждого базового типа данных x может принимать разные значения, представляя размер данных. Таким образом, отправитель отправляет со своей машины HtoNl (хост для сети LONG), и эта функция преобразует данные в интерпретацию сети (т. Е. Большой конец). Приемник выполнит NtoHl (сеть будет размещать LONG), и эта функция преобразуется из сетевой интерпретации в собственную интерпретацию машины (если его собственная машина также является большой энтикой, то функция NtoHl является функцией идентификации).