LINUX.ORG.RU

Всем привет! есть переменная типа short (причем signed !). ее необходимо загнать в unsigned char массив, для дальнейшей передачи по сети. Научите как это делать, плиз!! ps язык с++

используй объединение

union U
{
  short s;
  unsigned char b[sizeof(short)];
};
emulek
()

man sizeof, man typecasting, man другие ЯП

wota ★★
()
Ответ на: комментарий от emulek

и да, надо заметить, что в разных компьютерах short может быть разным. Т.ч. это может привести к fail'у. Сейчас в short 4 char'а в большинстве архитектур, но завтра может стать по другому. Раньше было всего 2 чара.

emulek
()
Ответ на: комментарий от emulek

и да, для совместимости ИМХО есть смысл преобразовать short в int32_t, и надеяться на то, что в char'е будет всегда 8 бит, а short не станет никогда больше 4х байт.

emulek
()

Можете передавать short по сети сразу, без загона в массив char'ов. Независимо от этого, ничего хорошего у Вас не выйдет.

Sorcerer ★★★★★
()
Ответ на: комментарий от emulek

Да, строго говоря, short не обязан быть равным 2 байта, согласен. Но пока что это вроде везде так.

Вообще, я уже давно перелез на Qt (ибо все-равно интерфейс на нем пишу), а там есть quint8 и quint16 соответственно.

Так то, конечно, твой вариант более правильный..

solovey ★★
()
Ответ на: комментарий от solovey

Вообще, я уже давно перелез на Qt (ибо все-равно интерфейс на нем пишу), а там есть quint8 и quint16

в стандарте уже давно есть int8_t и прочее такое.

emulek
()
Ответ на: комментарий от kolya38

а на приемной стороне как из uchar в short ?

наоборот. А что объединением не хочешь? В этих сдвигах ты обязательно со знаками запутаешься.

emulek
()
Ответ на: комментарий от kolya38

Если сдвигами, то как-то так

unsigned char arr[2] = {твои данные};
short var = (arr[1] << 8) + arr[0];
Да, это по прежнему вполне себе говнокод. Лучше, наверное, делать с union'ами

solovey ★★
()
Ответ на: комментарий от emulek

Это точно. Я, правда, плюсы никогда нормально не знал, сразу с чистого Си перелез на Qt, когда надо было гуй нарисовать

solovey ★★
()

Для передачи по сети никогда не пользуйся встроенными типами, используй типы с явной размерностью - int(8|16|32|64)_t, uint(8|16|32|64)_t. Иначе в один прекрасный день обнаружишь, что передача между машинами с разными архитектурами внезапно не работает. А может даже и с одинаковыми, но с разными флагами компиляции. Лучше заранее подстраховаться, тем более что на производительность это никак не влияет

marvin_yorke ★★★
()
Ответ на: комментарий от kolya38

ps сдвигами просто привычнее

ну вот и отвыкай. Сдвиги неожиданно себя ведут со знаковыми числами. Если -1 сдвинуть вправо, получится ВНЕЗАПНО -1. А может получится и 127. Оба ответа правильные, по стандарту, и Ъ.

emulek
()
Ответ на: комментарий от marvin_yorke

Для передачи по сети никогда не пользуйся встроенными типами

ещё в файлы не нужно пихать int'ы. По той же причине.

emulek
()

Ещё неплохо использовать network byte order.

backbone ★★★★★
()
Ответ на: комментарий от solovey

Вообще, я уже давно перелез на Qt (ибо все-равно интерфейс на нем пишу), а там есть quint8 и quint16 соответственно.

man stdint.h

andreyu ★★★★★
()

Совсем того все? Какие сдвиги, какое это все?

char *s;
short h;
((uint16_t *)s)[0] = htons(h);

Запись в массив можно и докторовским способом через union.

arturpub ★★
()
Ответ на: комментарий от xeiph

А как же endianness?

а никак. Всё будет работать, пока оно одно и то же. TCP жеж работает, и ведь в тамошних пакетах не указано, как интерпретировать контрольную сумму.

emulek
()

short
для дальнейшей передачи по сети

htons(reinterpret_cast<unsigned short>(yourshort));

не?

Stil ★★★★★
()
Ответ на: комментарий от emulek

и что это даст? ему надо гарантировать одинаковый эндианнесс с обоих сторон, а значит, просто так писать в сокет нельзя, при любом раскладе надо сначала конвертировать в определенный эндианнесс (в какой хочешь, главное — в один и тот же с обоих сторон).

val-amart ★★★★★
()
Ответ на: комментарий от val-amart

и что это даст? ему надо гарантировать одинаковый эндианнесс с обоих сторон

это ему даст то, что его программа не будет работать с другим эндианнессом. О чём собственно и речь. Также она не будет работать с другим sizeof(short) и с другим размером char.

emulek
()
Ответ на: комментарий от emulek

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

val-amart ★★★★★
()
Ответ на: комментарий от val-amart

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

проблема в принципе не решаемая. Для максимальной производительности необходимо, что-бы объекты в ЯП отображались прямо на объекты в вычислителе, а это невозможно, т.к. вычислители разные. Потому требуется зафиксировать какой-то стандарт, и его планомерно придерживаться при любых коммуникациях. Но никак не в самом ЯП, ибо получаться строчки как в паскале, длинна которых ВСЕГДА 0..255 байт. (эта строчка более чем в трое длиннее, мне что, теперь убиться?)

emulek
()
Ответ на: комментарий от emulek

Уже все придумано давно, поищи в гугле про сетевой порядок байт.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.