Почему данные, передаваемые по сети, преобразуются в сетевой порядок байтов?

Я не уверен, как использовать 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).

  1. А имеет номер 0x44332211 в памяти как 44 33 22 11,
  2. Звонки htonl() так как программа была написана для переносимости.
  3. Число по- прежнему представляется как 44 33 22 11 и отправил по проводу.
  4. Б получает 44 33 22 11 и помещает это через ntohl(),
  5. B получает значение, представленное 11 22 33 44 от ntohl() и помещает его в соответствующую переменную, которая затем приводит к 0x44332211 как и хотел.

Опять же, необходимость всегда вызывать эти функции избавляет вас от размышлений о том, для какой машины вы программируете - просто программируйте для всех типов машин и вызывайте каждую из этих функций, когда они необходимы.

Тот же пример можно выразить, не зная, являются ли A или B BE или LE:

  1. А имеет номер 0x44332211 в памяти.
  2. Звонки htonl() так что номер отправляется как 44 33 22 11 по проводу. Делается ли это путем возврата или выхода из него, определяется порядком номера хозяина B.
  3. Б получает 44 33 22 11 и помещает это через ntohl(), Это меняет или нет, в зависимости от порядкового номера узла B.
  4. 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 функции существуют, потому что нет способа посмотреть на число и узнать, является ли он старшим или младшим, поэтому получатель не может быть уверен, какой способ интерпретировать байты

Другие вопросы по тегам