2010-03-25 4 views
2

Теперь я борюсь с программированием сокетов, и я столкнулся с проблемой, которую я не знаю, как решить переносимым образом. Задача проста: мне нужно отправить массив из 16 байтов по сети, получить его в клиентском приложении и проанализировать его. Я знаю, что есть такие функции, как htonl, htons и т. Д., Которые можно использовать с uint16 и uint32. Но что мне делать с кусками данных больше?Отправка массива произвольной длины через сокет. Endianness

спасибо.

ответ

3

Вы говорите массив из 16 байт. Это не помогает. Endianness имеет значение только для вещей, больших байта.

Если это действительно сырые байт, то просто отправить их, вы получите их точно так же

Если это действительно структура вы хотите отправить его

struct msg 
{ 
    int foo; 
    int bar; 
..... 

Затем вам нужно работать через буфер вытягивая эти значения.

При отправке необходимо собрать пакет в стандартном порядке

int off = 0; 
*(int*)&buff[off] = htonl(foo); 
off += sizeof(int); 
*(int*)&buff[off] = htonl(bar); 
... 

когда вы получаете

int foo = ntohl((int)buff[off]); 
off += sizeof(int); 
int bar = ntohl((int)buff[off]); 
.... 

EDIT: Я вижу, что вы хотите, чтобы отправить адрес IPv6, они всегда находятся в сети байтовый порядок - так что вы можете просто передать его в исходное состояние.

1

htons, htonl и т. Д. Предназначены для работы с одним элементом данных (например, int), который превышает один байт. Массив байтов, в котором каждый из них используется как отдельный элемент данных (например, строка), не обязательно должен быть переведен между хостом и сетевым порядком байтов.

+0

Я немного смущен. Скажем, моя машина имеет порядок байтов младшего порядка, и я пытаюсь отправить ipv6-адрес в виде байтового массива в одном блоке по сети. Насколько я понимаю, мы должны вернуть байты (16-й станет первым), перенести их и на стороне клиента (если это тоже мало-endian) вернуть байта-ордера. Я прав? –

+0

IPv6-адрес должен быть отправлен в виде массива в порядке big-endian. Вы должны (обычно) иметь возможность обрабатывать его как в основном непрозрачные данные - например, вы получаете 16 байт и копируете их в sockaddr_in6 точно так же, как вы их получили.Стек IP может решить поменять их внутри, но все, что вы должны видеть снаружи, будет в сетевом порядке. Когда-нибудь, если бы у вас была 128-битная машина и вы хотели загрузить ее и манипулировать ею как число, тогда вам придется беспокоиться о 'ntohlll' и' htonlll' (или о том, что получилось). –

3

Endianness - свойство многобайтовых переменных, таких как 16-битные и 32-разрядные целые числа. Это связано с тем, идет ли первый или младший байт первым. Если клиентское приложение обрабатывает массив как отдельные байты, ему не нужно беспокоиться о контенте, поскольку порядок бит в байтах одинаковый.

1

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

В вашем конкретном случае это сводится к пониманию того, что получатель будет делать с вашими 16 байтами. Если он будет обрабатывать каждый из 16 записей в массиве в виде отдельных однобайтовых значений, вы можете просто отправить их, не беспокоясь о endiannes. Если, с другой стороны, приемник будет обрабатывать ваш 16-байтовый массив как четыре 32-битных целых числа, тогда вам нужно будет запускать каждое целое число через hton() перед отправкой.

Помогло ли это?

Смежные вопросы