Почему данные, передаваемые по сети, преобразуются в сетевой порядок байтов?
Я не уверен, как использовать hton()
, Теория заключается в том, что любые данные, передаваемые по сети, должны иметь сетевой байтовый формат (т.е. порядок с прямым порядком байтов). Предположим, что клиент A поддерживает порядок байтов, а B поддерживает порядок байтов. Я отправляю данные из A в B, и данные читаются как многобайтовые. Затем в сети нам нужно преобразовать данные в сетевой порядок байтов, используя htonl()
а также htons()
, Так как клиент A уже является байтовым порядком байтов, htonl()
а также htons()
вернуть тот же вывод. Но B имеет младший порядок, поэтому эти функции меняют порядок. Учитывая это, как мы можем сказать, что соблюдение общего формата (т. Е. С прямым порядком байтов) является решением проблемы, когда машинам с большим и меньшим порядком байтов необходимо общаться?
2 ответа
Я попробую по-другому, показывая весь поток:
Отправка 0x44332211
по проводам всегда происходит как 44 33 22 11
, Отправителя htonl()
обеспечивает это либо путем изменения порядка следования байтов (на машинах LE), либо просто оставляя их такими, какие они есть (на машинах BE). Приемник поворачивает 44 33 22 11
в 0x44332211
с ntohl()
- опять же, либо возвращая их, либо оставляя их.
Упомянутые функции {hton,ntoh}{l,s}()
помогите программировать в портативном режиме: независимо от того, настроена ли программа на машине LE или BE, они всегда работают так, как должны. Таким образом, даже на машинах BE функции должны вызываться, даже если они являются noops.
Пример:
A (BE) хочет отправить 0x44332211
в B (LE).
- А имеет номер
0x44332211
в памяти как44 33 22 11
, - Звонки
htonl()
так как программа была написана для переносимости. - Число по- прежнему представляется как
44 33 22 11
и отправил по проводу. - Б получает
44 33 22 11
и помещает это черезntohl()
, - B получает значение, представленное
11 22 33 44
отntohl()
и помещает его в соответствующую переменную, которая затем приводит к0x44332211
как и хотел.
Опять же, необходимость всегда вызывать эти функции избавляет вас от размышлений о том, для какой машины вы программируете - просто программируйте для всех типов машин и вызывайте каждую из этих функций, когда они необходимы.
Тот же пример можно выразить, не зная, являются ли A или B BE или LE:
- А имеет номер
0x44332211
в памяти. - Звонки
htonl()
так что номер отправляется как44 33 22 11
по проводу. Делается ли это путем возврата или выхода из него, определяется порядком номера хозяина B. - Б получает
44 33 22 11
и помещает это черезntohl()
, Это меняет или нет, в зависимости от порядкового номера узла B. - B получает значение
0x44332211
как и хотел.
Я думаю, вы думаете, что клиент B, видящий байты в "обратном порядке", означает, что они не правы. Байты будут в обратном порядке по сравнению с клиентом A, но это потому, что клиент A интерпретирует целые числа в обратном направлении от клиента B; оба будут интерпретировать его как одно и то же число в конце. Например, одна машина будет представлять число 4 как 00 00 00 04
, Другой будет представлять это как 04 00 00 00
, но оба все равно будут видеть это как 4 - если вы добавите 1 к нему, вы получите 00 00 00 05
а также 05 00 00 00
соответственно. hton
/ntoh
функции существуют, потому что нет способа посмотреть на число и узнать, является ли он старшим или младшим, поэтому получатель не может быть уверен, какой способ интерпретировать байты