С++ Порядок байтов в программировании сокетов

В C++ мы отправляем данные, используя сокет в сети. Я знаю, что нам нужно использовать функции htons() , ntohs() для поддержания порядка следования байтов big endian и little endian< /сильный>.

поддержка у нас есть следующие данные для отправки

int roll;
int id;
char name[100];

Это также может быть обернуто в структуру.

Меня смущает то, что для roll и id мы можем использовать функцию htons(). Но что и как делать для строки name? Нужно ли нам использовать какую-либо такую ​​функцию? будет ли он работать на каждой машине, такой как Mac, Intel и другие сети?

Я хочу отправить все три поля в одном пакете.


person Vijay    schedule 30.06.2011    source источник


Ответы (3)


Вы бы использовали htonl вместо int, а не htons.

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

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

person Marcelo Cantos    schedule 30.06.2011
comment
@marcelo: наверное, многобайтовый символ? 0x0001 становится 0x0100? - person Donotalo; 30.06.2011
comment
Марсело Кантос, похоже, ты прав. нужна дополнительная информация. Благодарность - person Vijay; 30.06.2011
comment
@Vijay: На всех платформах, кроме самых странных, char имеет тот же размер, что и байт: восемь бит. Когда вы говорите многобайтовый, я предполагаю, что вы имеете в виду широкие символы, или wchar_t, которые обычно имеют 16 бит, но иногда 32 бита. В любом случае, можно с уверенностью предположить, что char будет кодироваться как единое целое на любом транспорте на основе IP. Если вы хотите отправить Unicode, обычно лучше передавать кодировку UTF-8, а не широкие символы. - person Marcelo Cantos; 30.06.2011
comment
@Marcelo Cantos - ты снова прав. но меня смущает. Широкие символы, если я xmit без преобразования, они будут работать? utf8 сам по себе похож на массив символов, поэтому он будет работать. запутанно для меня сейчас - person Vijay; 30.06.2011
comment
Широкие символы больше байта, поэтому для них необходимо скорректировать порядок байтов (htons), если вы хотите, чтобы ваш формат передачи был нейтральным по порядку байтов. Как вы указываете, кодировка UTF-8 определяет кодировку на уровне символов (массив байтов), поэтому у нее нет таких проблем. - person Marcelo Cantos; 30.06.2011

Для символьных массивов это преобразование не требуется, поскольку они не имеют сетевого порядка байтов, а передаются последовательно. Причина существования ntohs и htons заключается в том, что некоторые типы данных состоят из младших и старших битов, которые по-разному интерпретируются в разных архитектурах. Это не относится к строкам.

person Constantinius    schedule 30.06.2011
comment
на самом деле, для тех, кто имеет порядок байтов, это проблема. - person diverscuba23; 30.06.2011
comment
Ты имеешь в виду струны? Нет, а почему должно быть? - person Constantinius; 30.06.2011
comment
Я имел в виду ntohs и htons и связанные с ними функции. Не выполняйте никакой перестановки битов в каждом байте, просто поменяйте порядок байтов, если порядок байтов хоста отличается от порядка байтов в сети. - person diverscuba23; 30.06.2011
comment
@diverscuba23: Вам не нужно заботиться о бит-сексе, поскольку наименьшая единица, которую вы можете использовать, — это байт. Бит-секс будет иметь значение только в аппаратном обеспечении. - person DarkDust; 30.06.2011

Чтобы добавить полезные комментарии здесь - если ваши структуры становятся намного более сложными, вам может быть лучше рассмотреть библиотеку сериализации, например Boost.Serialization или Буферы протокола Google, которые скрытно обрабатывают порядок следования байтов.

При кодировании строки убедитесь, что вы отправляете длину (возможно, short, обработанную с помощью htons) перед самой строкой, а не просто отправляете 100 символов каждый раз.

person Steve Townsend    schedule 30.06.2011