С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.55/40: Рейтинг темы: голосов - 40, средняя оценка - 4.55
12 / 12 / 2
Регистрация: 04.08.2011
Сообщений: 57

Передача по UDP числа и массива в одном пакете

06.08.2012, 15:16. Показов 8145. Ответов 26
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Я в С++ новичок. Задача следующая: нужно передать по UDP пакет в котором первые 4 байта было бы число указывающие на кол-во записей в массиве (4 байта т. к. int), а потом шел массив структур.
Вот, например, есть у меня структура:
C++
1
2
3
4
struct DIAG_DATE
{   int Day;
    int Month;
    int Year;};
Создаю массив таких структур
C++
1
struct DIAG_DATE mas[10];
После заполнения массива, а хочу передать его по UDP:
C++
1
sendto(sSocket,(char *)mas, sizeof(mas), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
Как вместить в начало пакета число int?
Заранее спасибо.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
06.08.2012, 15:16
Ответы с готовыми решениями:

Подмена source IP в UDP пакете
Проблема такая: есть сервер-принимающий от кучи девайсов данные по UDP. Различает сервер девайсы по их IP. Задача написать эмулятор,...

Передача массива байтов по UDP протоколу другому приложению
Как в BorlandС++ Builder6 решается вопрос обмена информацией с другими приложениями (не обязательно созданными в С++ Builder)? Например,...

Передача с микрофона в udp и прием из udp на динамик
Собственно каким образом осуществить передачу данных с микрофона в сеть и прием из сети данных вывести на звуковое устройство. проект...

26
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
06.08.2012, 15:37
C++
1
2
3
int size;
//...
sendto(sSocket, (char*)(&size), sizeof(int), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
0
12 / 12 / 2
Регистрация: 04.08.2011
Сообщений: 57
06.08.2012, 15:56  [ТС]
Спасибо за ответ, Jupiter. Но разве так число не будет идти отдельным пакетом?
0
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
06.08.2012, 16:01
Jupiter, тогда массив пойдет отдельным пакетом (не факт, что первым).
Sanuch89, придется завести отдельную область памяти размером не более предельного размера пакета хранящую в начале индекс первого элемента части массива передаваемой в пакете и количество элементов части массива передаваемой в пакете, пробегать по массиву и передавать его по кусочкам предварительно копируя в описанную служебную область с заполнением соответствующих полей.

Добавлено через 1 минуту
...ну или если он умещается в один пакет все закончится на первом же пакете, а передавать начальный индекс будет необязательно
1
12 / 12 / 2
Регистрация: 04.08.2011
Сообщений: 57
06.08.2012, 16:16  [ТС]
Спасибо, Vxg. Я примерно понял, вот только не знаю как реализовать твои слова.

Я пробовал реализовать все через массив
C++
1
char* mas[10];
Передавая туда в первый элемент ссылку на число, а остальными элементами массива были ссылки на структуры.
Но после передачи клиентом
C++
1
sendto(sSocket,(char *)mas, sizeof(mas), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
сервер принимал не верный пакет.
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
06.08.2012, 16:17
Sanuch89, передавай размер массива как его нулевой элемент а само наполнение массива индексируй с 1-го элемента, т.е вместо N элементов в передаваемом массиве будет N + 1 элемент - просто и сердито
0
12 / 12 / 2
Регистрация: 04.08.2011
Сообщений: 57
06.08.2012, 16:23  [ТС]
Юра, так я и пытался сделать. А как в массив запихнуть разные типы данных? Только если массив типа char* mas[10]? Или можно как-то?
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
06.08.2012, 16:25
Цитата Сообщение от Sanuch89 Посмотреть сообщение
А как в массив запихнуть разные типы данных?
- тогда используй массив структур аля
C++
1
2
3
4
5
6
7
8
struct data
{
   int iVal;
   double dVal;
};
 
data array[11] = {0};
array[0].iVal = 10;//Записываем в первое поле 1-й структуры число элементов
а далее в цилке делаем наполнение остальных структур
1
12 / 12 / 2
Регистрация: 04.08.2011
Сообщений: 57
06.08.2012, 16:32  [ТС]
Спасибо, Юра. Получается к своей структуре мне нужно добавить int iVal. Она будет заполнена только в нулевом элементе массива, а в остальных она будет пуста? А память под нее будет выделяться и расходоваться в пустую...
0
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
06.08.2012, 16:35
Sanuch89, на всякий случай: если нет крайних обостоятелеств, вынуждающих использовать udp, то нужно использовать tcp. непременно.
0
12 / 12 / 2
Регистрация: 04.08.2011
Сообщений: 57
06.08.2012, 16:40  [ТС]
novi4ok, знаю. Нужна быстрая передача большого количества однотипных данных. Не я так решил Просто выполняю задание.
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
06.08.2012, 16:50
Цитата Сообщение от Sanuch89 Посмотреть сообщение
Она будет заполнена только в нулевом элементе массива, а в остальных она будет пуста?
- да нет же в остальных элементах твои данные, ведь это твои слова

Цитата Сообщение от Sanuch89 Посмотреть сообщение
А как в массив запихнуть разные типы данных?
я тебе и ответил делай массив структур вот такого массива в котором в перемешку идут int, double, char объявить нельзя а с помощью структур можно. Я не вижу какие именно данные ты хочешь передавать поэтому написал абстрактный пример struct data, если надо конкретика напиши что именно хочешь передать, т.е что идёт первым элементом, что вторым... что 10-м а я уже подберу оптимальную структуру

Добавлено через 2 минуты
Сообщение от Sanuch89
А как в массив запихнуть разные типы данных?
а теперь пишешь это:
Цитата Сообщение от Sanuch89 Посмотреть сообщение
Нужна быстрая передача большого количества однотипных данных. Не я так решил
-
Тогда задание решается вообще просто
int mass[11] = {0};
mass[0] = 10;
в остальных элементах твои значения
0
12 / 12 / 2
Регистрация: 04.08.2011
Сообщений: 57
06.08.2012, 17:01  [ТС]
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Тогда задание решается вообще просто
int mass[11] = {0};
mass[0] = 10;
в остальных элементах твои значения
не пойдёт. Нужно чтобы нулевым элементом было число передаваемых записей. Это число будет выступать в роли счётчика на принимающей стороне.

Структура такая:
C++
1
2
3
4
struct DIAG_DATE
{ int Day;
 int Month;
 int Year;};
Заранее спасибо.
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
06.08.2012, 17:13
Цитата Сообщение от Sanuch89 Посмотреть сообщение
Нужно чтобы нулевым элементом было число передаваемых записей. Это число будет выступать в роли счётчика на принимающей стороне.
Sanuch89, вот смотри чем этот вариант отличен от того который я привёл

Моя цитата
тогда используй массив структур аля
struct data
{
int iVal;
double dVal;
};

data array[11] = {0};
array[0].iVal = 10;//Записываем в первое поле 1-й структуры число элементов
а далее в цилке делаем наполнение остальных структур


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct DIAG_DATE
{ 
    int Day;
    int Month;
    int Year;
};
 
DIAG_DATE array[11] = {0};
array[0].Day             = 10;//Всё при получении парсь именно это поле в самой первой структуре
//далее как либо наполни свои оставшиеся 10 структур
array[1].Day = 12;
array[1].Month = 12;
array[1].Year = 2012;
//и т.д.
а затем array запихни в SendTo
1
12 / 12 / 2
Регистрация: 04.08.2011
Сообщений: 57
06.08.2012, 17:22  [ТС]
Ага, вот теперь понял, что ты имел ввиду Спасибо!
А чисто теоретически, можно сделать чтобы первыми в пакете были именно 4 байта int'a, а не структура?
0
06.08.2012, 17:34

Не по теме:

Цитата Сообщение от Sanuch89 Посмотреть сообщение
А чисто теоретически, можно сделать чтобы первыми в пакете были именно 4 байта int'a, а не структура?
- нет в одном пакете не думаю:pardon:

0
12 / 12 / 2
Регистрация: 04.08.2011
Сообщений: 57
06.08.2012, 17:49  [ТС]
Ещё раз спасибо
0
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
06.08.2012, 19:45
Никто не упомянул довольно важный момент (я не знаю, нужно ли это писать и в курсе ли автор темы, просто почему-то никто никогда об этом не пишет):

1) Хранение многобайтовых целых в компьютере зависит от архитектуры процессора ( Ознакомиться можно тут http://ru.wikipedia.org/wiki/Порядок_байтов )

2) Чтобы программа работала на разных архитектурах, необходимо преобразовывать мультибайтовые целые в сетевой порядок байтов перед отправкой, а также проделывать обратную операцию после их получения на приёмнике. Тут ещё немного по теме и по функциям http://beej.us/guide/bgnet/out... #byteorder

Если этого не сделать, то есть шанс получить мусор на приёмнике.
1
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
07.08.2012, 12:08
необязательно делать первую запись массива фиктивной и использовать ее для хранения количества элементов.
если вы хотите одновременно работать с массивом структур и передавать его вам подойдут конструкции вида:
C++
1
2
3
4
5
6
7
8
union
{
    int count; //количество фактически передаваемых элементов
    DIAG_DATE value[100]; //100 так как мы не должны превысить максимально допустимый размер пакета, количество фактически передаваемых элементов может быть меньше (массив в этом случае частично пуст)
}
buffer;
//...
sendto(s, (char *)&buffer, sizeof(int) + buffer.count * sizeof(DIAG_DATE), 0, (SOCKADDR *)&sa, sizeof(sa));
если количество элементов велико и вы передаете массив по частям вам нужно предварительно копировать участки массива в буфер при помощи конструкции вида
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
union
{
    int idx; //индекс первого элемента
    int count;
    DIAG_DATE value[100];
}
buffer;
//...
//наш большой массив
DIAG_DATE value[1000];
//пусть мы передаем 100 элементов начиная со второй сотни
buffer.idx = 200;
buffer.count = 100;
memcpy(&buffer.value, &value[buffer.idx], buffer.count * sizeof(DIAG_DATE));
при этом нужно не забывать о том что последняя передача может содержать количество элементов отличное от 100 (частично заполненный пакет). на принимающей стороне нужно быть готовым к тому что часть пакетов может быть потеряна и к тому что пакеты могут приходить в произвольном хронологическом порядке. если ваша задача чувствительна к этому придется писать свой "протокол": в простейшем случае добавить в начало пакета его номер (увеличивающийся счетчик) и следить на принимающей стороне за тем что бы в номерах не было разрывов (что бы всегда увеличивался только на единицу). при обнаружении сбоя передачи - запрашивать повтор начиная с последнего правильного пакета. это если очень упрощенно излагать.

Добавлено через 2 часа 18 минут
...пардон, вместо union пишем struct
1
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
07.08.2012, 14:48
И что, никто не вспомнил про сериализацию? "Стыдно, товарищи!" (с)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.08.2012, 14:48
Помогаю со студенческими работами здесь

Классы в одном пакете, но не видят друг друга
Пожалуйста, скажите почему класс Manager не видит класс Emploee? package com.regi.inheritance; public class Manager extends...

Мантисса числа в пакете Mathematica
Добрый день всем! Помогите, пожалуйста, продвинутые пользователи пакета Mathematica! Проблема такая: Провожу в пакете...

передача по udp
При передаче байт по протоколу udp я же могу предсказать сколько байт отправится за один раз функцией send() - на клиенте и сколько байт...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru