The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"куда пихать byte,word,dword ?"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"куда пихать byte,word,dword ?"  +/
Сообщение от Ivanoff (ok) on 12-Май-08, 14:14 
Я начинающий :) пишу сетевую программку для некоторого протокола.
Проблема встала куда запихать пакет, пакет примерно выглядит так:
тип
byte type
word head
dword body
И того пакет 6 байт.

пока делаю так, пакет получаю в буффер char buff[];
а потом, когда надо анализировать, например посмотреть внутренности делаю так:
cout << "Type: " << buff[0] << endl;
cout << "Head: " << (int)buff[1]*10+buff[2] << endl;
cout << "Body: " << buff[3]*100+buff[4]*100+buff[5]*10+buff[6] << endl;

1. На сколько это корректно?
2. Может есть способы поэлегантнее доставать данные из пакета например body?
3. Есть ли какие нибудь стандартные типы(C/C++) для хранения байта, слова, двойного слова?


Высказать мнение | Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "куда пихать byte,word,dword ?"  +/
Сообщение от NuINu (??) on 12-Май-08, 15:13 
>Я начинающий :) пишу сетевую программку для некоторого протокола.
>Проблема встала куда запихать пакет, пакет примерно выглядит так:
>тип
>byte type
>word head
>dword body
>И того пакет 6 байт.

это из какого языка типы? интересно как красивая цифра 6 получилась.

>
>пока делаю так, пакет получаю в буффер char buff[];
>а потом, когда надо анализировать, например посмотреть внутренности делаю так:
>cout << "Type: " << buff[0] << endl;
>cout << "Head: " << (int)buff[1]*10+buff[2] << endl;
>cout << "Body: " << buff[3]*100+buff[4]*100+buff[5]*10+buff[6] << endl;

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

>
>1. На сколько это корректно?
>2. Может есть способы поэлегантнее доставать данные из пакета например body?
>3. Есть ли какие нибудь стандартные типы(C/C++) для хранения байта, слова, двойного
>слова?

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

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "куда пихать byte,word,dword ?"  +/
Сообщение от Ivanoff (ok) on 12-Май-08, 16:43 
>это из какого языка типы?
>

Это... не из какого это выдержка из описания протокола. Как бы вроде известно что:
byte - байт это 8 бит. Бит это минимальная единица информации :) может принимать значения 0 или 1 :)

> интересно как красивая цифра 6 получилась.

Да, вы правы ) опечатка вышла поле Type(1 байт),Head (word = 2 байта),
Body (dword = 4 байта ) в итоге имеем пакет 1+2+4=7 байт.

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

это десятки. хм, насчет порядка в word, в левом байте - старший, в правом младший.

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

С языком проблем нет, с конструкцией struct знаком.

Про то где хранить байт,слово, двойное слово и как выделять их из массива байт вы не сказали не слова ( имхо вопрос не раскрыт.


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "куда пихать byte,word,dword ?"  +/
Сообщение от NuINu (??) on 13-Май-08, 09:44 

>С языком проблем нет, с конструкцией struct знаком.

ну если вы так в этом уверены, тогда смотрите

typedef struct Test1_stru {
  unsigned char  byte;
  unsigned short int word;
  unsigned int   dword;
} __attribute__((__packed__)) Test1 ;

можете типы из glib взять, они переносимы и не зависят он архитектуры и компилятора.

>
>Про то где хранить байт,слово, двойное слово и как выделять их из
>массива байт вы не сказали не слова ( имхо вопрос не
>раскрыт.

Вы случаем преподавателем не работаете?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "куда пихать byte,word,dword ?"  +/
Сообщение от Ivanoff (ok) on 13-Май-08, 10:27 
>typedef struct Test1_stru {
>  unsigned char  byte;
>  unsigned short int word;
>  unsigned int   dword;
>} __attribute__((__packed__)) Test1 ;
>
>можете типы из glib взять, они переносимы и не зависят он архитектуры
>и компилятора.

спасибо )

>Вы случаем преподавателем не работаете?

нет, с чего вы взяли?


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "куда пихать byte,word,dword ?"  +/
Сообщение от anonymous (??) on 13-Май-08, 11:09 
>[оверквотинг удален]
>ну если вы так в этом уверены, тогда смотрите
>
>typedef struct Test1_stru {
>  unsigned char  byte;
>  unsigned short int word;
>  unsigned int   dword;
>} __attribute__((__packed__)) Test1 ;
>
>можете типы из glib взять, они переносимы и не зависят он архитектуры
>и компилятора.

Ага, а теперь начинается веселье.  Никто из вас двоих никогда не слышал такой термин как "порядок байтов"?  Little endian, big endian?  Что тот самый short можно передавать двумя байтами в разном порядке следования этих байтов в сетевом потоке?  И у разных машин в памяти он хранится по-разному?  И что читая/передавая такую структуру _напрямую_ вы заново изобретаете ту проблему, которая уже была решена на заре изобретения сетей?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "куда пихать byte,word,dword ?"  +/
Сообщение от NuINu (??) on 13-Май-08, 14:16 
> Никто из вас двоих никогда не
>слышал такой термин как "порядок байтов"?  Little endian, big endian?
> Что тот самый short можно передавать двумя байтами в разном
>порядке следования этих байтов в сетевом потоке?  И у разных
>машин в памяти он хранится по-разному?  И что читая/передавая такую
>структуру _напрямую_ вы заново изобретаете ту проблему, которая уже была решена
>на заре изобретения сетей?

Давайте уважаемый, без излишних обобощений и огульных обвинений. ничего щас не начнется.
Здесь нигде не рассматривался механизм передачи по сети.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "куда пихать byte,word,dword ?"  +/
Сообщение от anonymous (??) on 13-Май-08, 18:27 
>Давайте уважаемый, без излишних обобощений и огульных обвинений. ничего щас не начнется.
>
>Здесь нигде не рассматривался механизм передачи по сети.

Извините, если ответил грубо.

Просто у OP изначально была такая конструкция:
cout << "Body: " << buff[3]*100+buff[4]*100+buff[5]*10+buff[6] << endl;
То есть, у него была избыточная система счисления с основанием 10 и 256-ю цифрами (при условии, что первый коэффициент -- 1000, а не 100).  Каждая цифра передавалась одним байтом.

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

Если же писать/читать напрямую структуры, то:
* во-первых, прочитав число таким образом, мы не получим тот же результат, что и при чтении способом из исходного сообщения;
* во-вторых та самая проблема с порядком байтов.

Нужно было не показать, что можно читать/писать структуры, а рассказать, что в настоящих программах делают так:
1. выделить кусок памяти под пакет;
2. функциями htons(), htonl() перевести числа из локального порядка байтов в сетевой;
3. при помощи memcpy() переписать эти числа побайтово в выделеную память начиная с нужного байта;
4. отправить пакет.

1. получить пакет;
2. функцией memcpy() переписать данные из пакета в переменные соответствующего числового типа;
3. функциями ntohs(), ntohl() перевести числа из сетевого порядка байтов в локальный.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

10. "куда пихать byte,word,dword ?"  +/
Сообщение от NuINu (??) on 14-Май-08, 12:23 
>>Давайте уважаемый, без излишних обобощений и огульных обвинений. ничего щас не начнется.
>>
>>Здесь нигде не рассматривался механизм передачи по сети.
>
>Извините, если ответил грубо.

извиняю :), очень приятно иметь дело с вежливым человеком.

>
>Просто у OP изначально была такая конструкция:
>cout << "Body: " << buff[3]*100+buff[4]*100+buff[5]*10+buff[6] << endl;
>То есть, у него была избыточная система счисления с основанием 10 и
>256-ю цифрами (при условии, что первый коэффициент -- 1000, а не
>100).  Каждая цифра передавалась одним байтом.
>
>Эта конструкция хотя бы не была машинно-зависимой, она вычислится одинаково при любом
>порядке байтов в машине.
>

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

>Если же писать/читать напрямую структуры, то:
>* во-первых, прочитав число таким образом, мы не получим тот же результат,
>что и при чтении способом из исходного сообщения;

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


>[оверквотинг удален]
>
>3. при помощи memcpy() переписать эти числа побайтово в выделеную память начиная
>с нужного байта;
>4. отправить пакет.
>
>1. получить пакет;
>2. функцией memcpy() переписать данные из пакета в переменные соответствующего числового типа;
>
>3. функциями ntohs(), ntohl() перевести числа из сетевого порядка байтов в локальный.
>

ну да, а еще переписать пару учебников не только по программированию на си, но и по сетевому программированию.

занимается человек, и пусть себе занимается.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

11. "куда пихать byte,word,dword ?"  +/
Сообщение от anonymous (??) on 14-Май-08, 17:47 
>На мой взгляд, судя по совокупности ошибок, это никакая не избыточная система
>счисления, а просто еще одна ошибка.
>Но писать код на си, и составлять байтики туда сюда, моделируя некие
>системы счисления не используюя встроенных типов это просто глупо. Помоему не
>надо никакой машинной независимости... программист работая на си должен быть отвлечен
>от порядка байт, в котором храняться слова и др типы. для
>того он и разрабатывался этот си, что бы уйти от ассеблера.

Иногда в общем приходится.  Да и по сути, сами hton*() именно так могут быть реализованы (наложение битовой маски и сдвиг для выделение байтов, и потом сдвиг и объединение по ИЛИ выделенных байтов в нужном порядке).  В заголовках на моей системе, если компилятор GCC, то используется ассемблерная вставка с инструкцией bswap, а если не GCC -- то эти самые сдвиги.

>>Если же писать/читать напрямую структуры, то:
>>* во-первых, прочитав число таким образом, мы не получим тот же результат,
>>что и при чтении способом из исходного сообщения;
>
>не совсем понял что значит прочитать число таким образом?

Если из одного и того же потока прочитать структуру и прочитать тем методом, который был в исходном сообщении, результаты не совпадут (не из-за порядка байтов, а из-за "десятичной" системы счисления).  В принципе, если умножение на 10 это таки ошибка, то вопросов нет.  А вдруг у него какой-то странный протокол?..

>ну да, а еще переписать пару учебников не только по программированию на
>си, но и по сетевому программированию.
>
>занимается человек, и пусть себе занимается.

:)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

12. "куда пихать byte,word,dword ?"  +/
Сообщение от Аноним (??) on 14-Май-08, 19:26 
>программист работая на си должен быть отвлечен
>от порядка байт, в котором храняться слова и др типы. для
>того он и разрабатывался этот си, что бы уйти от ассеблера.

Нет. C - высокоуровневый ассемблер. Хотите ни о чем не думать - используйте более другие языки.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

15. "куда пихать byte,word,dword ?"  +/
Сообщение от NuINu (??) on 15-Май-08, 14:16 
>>программист работая на си должен быть отвлечен
>>от порядка байт, в котором храняться слова и др типы. для
>>того он и разрабатывался этот си, что бы уйти от ассеблера.
>
>Нет. C - высокоуровневый ассемблер. Хотите ни о чем не думать -
>используйте более другие языки.

ну а я не согласен :) Ассемблер высокоуровневый это вот макроассемблер. я еще помню макросы от Клиппера, когда на ассемблере можно было писать си подобный код. но тем неменее он всегда оставался машинно зависимым(это код).

си всеже другое дело.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

16. "куда пихать byte,word,dword ?"  +/
Сообщение от Аноним (??) on 16-Май-08, 19:19 
>ну а я не согласен :) Ассемблер высокоуровневый это вот макроассемблер.

Назовешь принцыпиальное отличие?

Макроассемблер + набор одинаковых макросов под разные архитектуры - вот тебе кроссплатформенность. После можно и оптимизатор прикрутить. Вот тебе и C.

А на C можно отключить оптимизацию и напихать в функции ассемблерных вставок - вот тебе непортабельный ассемблер.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

18. "куда пихать byte,word,dword ?"  +/
Сообщение от NuINu (??) on 19-Май-08, 10:11 
>>ну а я не согласен :) Ассемблер высокоуровневый это вот макроассемблер.
>
>Назовешь принцыпиальное отличие?
>

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

>Макроассемблер + набор одинаковых макросов под разные архитектуры - вот тебе >кроссплатформенность.

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

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

>После можно и оптимизатор прикрутить. Вот тебе и C.
>
>А на C можно отключить оптимизацию и напихать в функции ассемблерных вставок
>- вот тебе непортабельный ассемблер.

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

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

19. "куда пихать byte,word,dword ?"  +/
Сообщение от Аноним (??) on 21-Май-08, 21:24 
>Лингвистическое. Другой уровнень абстракции. Полное абстрагирование от архитектуры
> физической реализации процессора целевой системы. нет таких понятий как регистр,
> стек. хотя понятия памяти

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

> ну да, охота ваять собственный язык?

Речь идет об устройстве существующих языков.

> Макросы не переносимы. зачастую невозможно создать

Это решается введением стандарта как в C

> рутинных операций, при этом ни вкоем случае не создается архитектурно независимый код.

Повторяю, сделай макросы для всех поддерживаемых архитектур с одним и тем же интерфейсом. Будешь на таком макроассемблере писать кроссплатформенный код. Или ты думаешь gcc магически-автоматически генерирует код под любые архитектуры?

> И самое главное, глупо программировать на ассемблере не используя архитектурных
> особенностей процессора

О том, как надо писать, речи вообще не идет. Речь идет о том что C - высокоуровневый ассемблер.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

20. "куда пихать byte,word,dword ?"  +/
Сообщение от angra (ok) on 22-Май-08, 12:54 
Используя вашу логику любой компилируемый язык это высокоуровневый ассемблер. Если вам так удобно обобщать, то это ваше право, в конце концов кому-то вообще удобно нас всех называть обобщать под названием "компутерщик".
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

21. "куда пихать byte,word,dword ?"  +/
Сообщение от Аноним (??) on 22-Май-08, 21:40 
> Используя вашу логику

Это не моя логика.

> любой компилируемый язык это высокоуровневый ассемблер.

Не любой. Между C и C++ есть, например, принцыпиальная разница. В общем google в руки, честно не охото 100 раз говоренное повторять.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

22. "куда пихать byte,word,dword ?"  +/
Сообщение от angra (ok) on 23-Май-08, 01:16 
И что гуглить? Может лично ваши измышления на других сайтах, вы считаете себя настолько популярным и авторитетным источником? Между C и C++ разница есть, но вот с точки зрения _вашей_ логики и то и другое высокоуровневый ассемблер.
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

23. "куда пихать byte,word,dword ?"  +/
Сообщение от NuINu (??) on 23-Май-08, 09:28 
>И что гуглить? Может лично ваши измышления на других сайтах, вы считаете
>себя настолько популярным и авторитетным источником? Между C и C++ разница
>есть, но вот с точки зрения _вашей_ логики и то и
>другое высокоуровневый ассемблер.

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

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "куда пихать byte,word,dword ?"  +/
Сообщение от Аноним (??) on 14-Май-08, 01:14 
Корректно паковать типы данных в байты самому, так гарантированно не будет проблем с переносимостью между компиляторами, с размерами типов данных и порядком байт.

unsigned char buff[7];

buff[0] = byte_var & 0xff;
buff[1] = word_var & 0xff;
buff[2] = (word_var << 8) & 0xff;
buff[3] = dword_var & 0xff;
buff[4] = (dword_var << 8) & 0xff;
buff[5] = (dword_var << 16) & 0xff;
buff[6] = (dword_var << 24) & 0xff;

byte_var = buff[0];
word_var = buff[1] | ((word)buff[2] << 8));
dword_var = buff[3] | ((dword)buff[4] << 8)) | ((dword)buff[5] << 16)) | ((dword)buff[6] << 24));

word и dword - ваши типы для word и dword соответственно. Обычно нет смысла использовать для обоих что-либо отличное от (unsigned)int.

Кстати в такой структуре:

typedef struct Test1_stru {
  unsigned char  byte;
  unsigned short int word;
  unsigned int   dword;
} __attribute__((__packed__)) Test1 ;

поля лучше хранить в обратном порядке (самые широкие в начале), а все эти __attribute__((__packed__)) - ересь

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

24. "куда пихать byte,word,dword ?"  +/
Сообщение от Olle email(??) on 08-Сен-09, 15:21 
>[оверквотинг удален]
>unsigned char buff[7];
>
>buff[0] = byte_var & 0xff;
>buff[1] = word_var & 0xff;
>buff[2] = (word_var << 8) & 0xff;
>buff[3] = dword_var & 0xff;
>buff[4] = (dword_var << 8) & 0xff;
>buff[5] = (dword_var << 16) & 0xff;
>buff[6] = (dword_var << 24) & 0xff;
>

Скорее всего операция сдвига не << , а >>

unsigned char buff[7];

buff[0] = byte_var & 0xff;
buff[1] = word_var & 0xff;
buff[2] = (word_var >> 8) & 0xff;
buff[3] = dword_var & 0xff;
buff[4] = (dword_var >> 8) & 0xff;
buff[5] = (dword_var >> 16) & 0xff;
buff[6] = (dword_var >> 24) & 0xff;

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "куда пихать byte,word,dword ?"  +/
Сообщение от vvvua (ok) on 14-Май-08, 11:21 
Определиться нужно с порядком байт, формировать структуру и передавать.
Не забівать про то, что компилятор в сруктурах использует выравнивание. Т.е. sizeof(структура) может быть != сумме sizeof всех типов ее членов.
Вообще, есть на gamedev.ru примеры.
Если и клиент и сервер на полностью одинаковых операционке и архитектуре - можно формировать структуру, отсылать ее без конвертации и так же принимать.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

13. "куда пихать byte,word,dword ?"  +/
Сообщение от аноним on 14-Май-08, 19:39 
тут кто-то скажет медленно... но лучше конечно snprintf(str, 80, "%d %d %d\n", a, b, c) а на той стороне как получаем строку -- сразу же sscanf(str, " %d %d %d", &a, &b, &c). а про типы отличные от инта забить ))

зы. отцы говорят самый лучший (и самый кроссплатформенный) способ обойти LE/BE и т.п. проблемы - юзать символьные потоки. и в отладке проще будет.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

14. "куда пихать byte,word,dword ?"  +/
Сообщение от Аноним (??) on 14-Май-08, 20:55 
>зы. отцы говорят самый лучший (и самый кроссплатформенный) способ обойти LE/BE и
>т.п. проблемы - юзать символьные потоки. и в отладке проще будет.

Не бывает `самого' кроссплатформенного. Бывает кроссплатформенный и нет. Поток цифр нисколько не удобней в отладке чем поток байтов.

Вообще, и в XML запихнуть никто не мешает. Только надо сначала головой подумать, что больше подходит, а тем, кто слушает `отцов' эту голову оторвать за ненадобностью.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

17. "куда пихать byte,word,dword ?"  +/
Сообщение от аноним on 17-Май-08, 03:04 
ну вот сразу и прям так. просто предложил...
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру