Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.69/26: Рейтинг темы: голосов - 26, средняя оценка - 4.69
0 / 0 / 0
Регистрация: 05.10.2009
Сообщений: 27

Winsock2.h:udp фрагментирование данных

11.10.2009, 12:07. Показов 5270. Ответов 25
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток!

Подскажите пожалуйста, какие можно использовать средства (функции) для фрагментации большого буфера (большой в том смысл, что не влезет в один UDP пакет) так, чтобы можно было самому дописывать некоторые данные (для обеспечения гарантии доставки) к полученным фрагментам в каждый UDP пакет? И какой длины должны быть эти фрагменты?

P.S.: возможно кто-то даст ссылку, где можно посмотреть реализацию гарантированной доставки данных по UDP.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.10.2009, 12:07
Ответы с готовыми решениями:

Фрагментирование файла
Всем доброго времени суток. Пишу программу для работы с большими файлами. Файл состоит из блоков размером 512 байт. Каким образом при...

Передача большого объема данных по UDP
Здравствуйте, форумчане! Возникла у меня необходимость передавать большой объем данных по UDP. sendto() посылает буфер частями по...

UDP. Как реализовать возможность передачи разного количества данных?
Здравствуйте. Возник такой вопрос: Есть UDP приемник #pragma comment (lib, "ws2_32.lib") #include "stdafx.h" #include...

25
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
11.10.2009, 16:10
если это - требование, не завидую. или почему нельзя использовать TCP ? если нельзя, то нужно самому реализовать все то же, что уже имеется в TCP: разбиение и нумерация пакетов, отслеживание доставки, запросы на повторную передачу, сборка, ... зачем изобретать велик?
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
11.10.2009, 16:35
UDP протокол не гарантирует доставку. Все. Точка.
Если тебе нужна гарантия доставки, то используй TCP. Ну или пиши свой протокол поверх UDP - получится тот же TCP, только намного хуже по качеству
0
0 / 0 / 0
Регистрация: 05.10.2009
Сообщений: 27
11.10.2009, 17:12  [ТС]
За дурака не принимайте только Я знаю, что не гарантирует! Потому так вопрос и ставится... Вы видимо самого вопроса не поняли... Если так, то попробуйте еще раз прочитать
какие можно использовать средства (функции) для фрагментации большого буфера (большой в том смысл, что не влезет в один UDP пакет) так, чтобы можно было самому дописывать некоторые данные (для обеспечения гарантии доставки) к полученным фрагментам в каждый UDP пакет? И какой длины должны быть эти фрагменты?
0
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
11.10.2009, 18:19
Цитата Сообщение от Lowbacki Посмотреть сообщение
За дурака не принимайте только
"я знаю, ты думаешь, что я дурак!"

а я попробую снова задать тот же вопрос: а вдруг ответят?

почему нельзя использовать TCP

у нас в одном проекте тоже используется UDP, но мы ничего не можем поделать: другая сторона не поддерживает ничего другого.

но если мы собираемся

использовать средства (функции) для фрагментации большого буфера (большой в том смысл, что не влезет в один UDP пакет) так, чтобы можно было самому дописывать некоторые данные (для обеспечения гарантии доставки) к полученным фрагментам в каждый UDP пакет,

значит все в наших руках, мы можем на каждой стороне делать что хотим. и при этом выбираем все же UDP. навернякак причина есть. скажи какая?
0
0 / 0 / 0
Регистрация: 05.10.2009
Сообщений: 27
11.10.2009, 19:09  [ТС]
Какая разница в чём причина?! Какое это отношение имеет к делу?
0
Эксперт С++
 Аватар для odip
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
11.10.2009, 20:47
Ну интересуется человек.
Может ты неправильный метод решения задачи выбрал ?
Например может тебе лучше SCTP использовать ? (http://ru.wikipedia.org/wiki/SCTP)
0
0 / 0 / 0
Регистрация: 05.10.2009
Сообщений: 27
11.10.2009, 20:51  [ТС]
Просто поставлена школярская задача, т.е. не для практики в жизни. По существу может кто-нибудь помочь ?
0
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
12.10.2009, 00:30
Цитата Сообщение от Lowbacki Посмотреть сообщение
Просто поставлена школярская задача, т.е. не для практики в жизни. По существу может кто-нибудь помочь ?
весь функционалитет из tcp имплементировать не нужно, т.к. сложно и уровень всего один. в нашем случае было решено след. образом: каждое сообщение (то, что длинное, и его нужно передавать) передавалось несколькими кусками длиной Н. к каждому куску дописывался заголовок, который содержал номер сообщения (все нумеровались по восходящей), его общую длину, количество кусков, номер текущего куска, длину куска. принимающая сторона по завершению приема всего передавала подтверждение. если нумерация нарушалась, приемник передавал запрос на подтверждение, в котором сообщал номер последнего полученного куска. контрольная сумма, кажется, еще передавалась для всего пакета. этого было достаточно, срабатывало. дробить было нужно потому что было известно, что на линии имеется устройство, которое не работает с кусками длинее М. в TCP дробление происходит по мере надобности в узлах, и потом собирается на конечном узле. у нас задача была попроще и протокол определяла другая сторона примерно как я описал.
1
0 / 0 / 0
Регистрация: 05.10.2009
Сообщений: 27
12.10.2009, 12:55  [ТС]
Не совсем понял, очередная отправленная на приемник пронумерованная "порция" данных - это (?)один(?) UDP пакет с номером части сообщения, которую он несёт?
0
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
12.10.2009, 15:52
Цитата Сообщение от Lowbacki Посмотреть сообщение
Не совсем понял, очередная отправленная на приемник пронумерованная "порция" данных - это (?)один(?) UDP пакет с номером части сообщения, которую он несёт?
совершенно верно. нам известна физическая конфигурация сети, а также известно, что кусок длиной М проходит через любое устройство без разбивки или усечения. поэтому ни один пакет не должен быть длинее этой величины. зато имеется гарантия, что если пакет пришел, то он тут веь. в tcp, например, вы говорите
C++
1
int n = socket.Receive (buffer, sizeof (buffer));
, и читаете, скажем, 512 байт. хотя нам известно, что согласно нашему протоколу следующее сообщение должно бы иметь длину 2000 байт. но где-то по пути встретилось устройство, которое работает с пакетами макс. длиной 512, и эти 2000 были им разбиты на 4 части. собирать их в кучу - задача принимающей стороны. tcp лишь гарантирует, что мы получим все пакеты в правильном порядке. нам необходимо все равно реализовать какой-то хидер, который будет описывать каждое сообщение. запутал я тебя?
0
0 / 0 / 0
Регистрация: 05.10.2009
Сообщений: 27
12.10.2009, 20:48  [ТС]
Мне кажется у вас задача ставилась задача сложнее чем у меня..
Попробую спросить по-другому
В общем я думаю использовать функцию sendto() и передавать по одному udp-пакету приемнику. В каждом таком пакете находится partlen байт, из которых часть байт отвечают за гарантированную доставку этого пакета, а оставшаяся часть является частью сообщения, которое мы передаём.

Вопрос 1.
Таким образом, получаем вопрос
Дано: buffer - передаваеоме сообщение, buflen - его длина в байтах
Найти: partlen - длина в байтах
Вопрос 2.
И кстати, будет ли быстрее, если я буду подавать не по части данных, влезающих в один пакет, а по большей части? Имеется ввиду два варианта решения:
1) buflen == максимальной длине udp пакета, который точно придёт не разбившись по пути на несколько пакетов ни на одном устройстве
2) buflen == некоторой величине, что часть сообщения не влезет в один udp пакет. В этом случай нужно иметь ввиду, что
P(A)=e^k, где
P(A) - вероятность, что отправленный функцией sendto буфер buf придёт(не придётся делать
повторный запрос)
e - вероятность, что 1 отправленный udp-пакет придёт
k - количество udp-пакетов, на которое разбивает buf при отправке функцией sendto
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
12.10.2009, 21:47
Цитата Сообщение от novi4ok Посмотреть сообщение
если нумерация нарушалась, приемник передавал запрос на подтверждение, в котором сообщал номер последнего полученного куска.
Хмм.... Что-то представляется не больно то удачным. Пример: сообщение 12345, разбито на кусочки 1, 2, 3, 4, 5. На приемный конец успешно пришли кусочки 1, 3, 4, 5. Кусочек 2 потерялся где-то по дороге. Что должен передать приемник, и что потом должен сделать передатчик?
0
0 / 0 / 0
Регистрация: 05.10.2009
Сообщений: 27
13.10.2009, 12:34  [ТС]
В итоге мучает меня как с самого начла когда создавал тему в основном только один вопрос: какая максимальная длина buflen udp-пакета, который точно придёт не разбившись по пути на несколько пакетов ни на одном устройстве.

просто я думаю делать так:
1) разбил сообщение на части длиной partlen=buflen-headerlen, где headerlen - длина заголовка, который я сам буду дописывать к очередной части перед её отправкой;
2) беру очередную часть, записываю её в буфер buf, дописываю в buf заголовок(обеспечивающий гарантию доставки)
3) отправляю: sendto(buf,buflen,...);
Дальше возможны варианты: либо ждать пока придёт подтверждение о приходе отпраленного пакета, либо через некторый таймаут ждать от приемника номера не пришедших и последний пришедший.
4) через определённый таймаут
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
13.10.2009, 12:50
Цитата Сообщение от Lowbacki Посмотреть сообщение
В итоге мучает меня как с самого начла когда создавал тему в основном только один вопрос: какая максимальная длина buflen udp-пакета, который точно придёт не разбившись по пути на несколько пакетов ни на одном устройстве.
Ежели мой склероз мне не изменяет, все сети должны пропускать датаграммы размером 576 байт, не разбивая их на более мелкие. [Ну, за исключением совсем уже экзотических сетей.] Из этой величины вычти: 20 байт - размер IP заголовка, 8 байт - размер UDP заголовка, итого 548 байт останется на твои пользовательские данные. Как ты их заполнишь твоим протокольным заголовком (без него ты вряд ли обойдешься, как уже говорилось), собственно данными и, возможно, контрольной суммой, - решать тебе.....
1
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
13.10.2009, 13:54
Цитата Сообщение от CheshireCat Посмотреть сообщение
Хмм.... Что-то представляется не больно то удачным. Пример: сообщение 12345, разбито на кусочки 1, 2, 3, 4, 5. На приемный конец успешно пришли кусочки 1, 3, 4, 5. Кусочек 2 потерялся где-то по дороге. Что должен передать приемник, и что потом должен сделать передатчик?
приемник подтверждает каждый полученный кусок. если передатчик не получает подтверждения в течение определенного времени, он просто повторяет последний переданный. у нас задача была несколько сложнее, было несколько сценариев:
- "центр" шлет сообщение устройству
- "центр" шлет запрос устройству, на которое ожидает ответа
- устройству шлет запрос центру и ожидает ответа

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

Добавлено через 2 минуты
Цитата Сообщение от Lowbacki Посмотреть сообщение
В итоге мучает меня как с самого начла когда создавал тему в основном только один вопрос: какая максимальная длина buflen udp-пакета, который точно придёт не разбившись по пути на несколько пакетов ни на одном устройстве.

просто я думаю делать так:
1) разбил сообщение на части длиной partlen=buflen-headerlen, где headerlen - длина заголовка, который я сам буду дописывать к очередной части перед её отправкой;
2) беру очередную часть, записываю её в буфер buf, дописываю в buf заголовок(обеспечивающий гарантию доставки)
3) отправляю: sendto(buf,buflen,...);
Дальше возможны варианты: либо ждать пока придёт подтверждение о приходе отпраленного пакета, либо через некторый таймаут ждать от приемника номера не пришедших и последний пришедший.
4) через определённый таймаут
у вас какие сценарии возможны? сами ли вы их определяете, или "поставлены в обстоятельства"? всегда ли передачу инициирует одна и та же сторона?
0
0 / 0 / 0
Регистрация: 05.10.2009
Сообщений: 27
13.10.2009, 14:26  [ТС]
Сам определяю (пишу и клиент, и сервер). Сценарии... Не совсем понял. Просто хочу написать две функции Send и Recv. Первая гарантировано отправляет сообщение, а вторая принимает его соответствующим образом.

у вас какие сценарии возможны? сами ли вы их определяете, или "поставлены в обстоятельства"? всегда ли передачу инициирует одна и та же сторона?
И сервер, и клиент будут использовать функции и Send, и Recv, но они только "говорят" что отправить или куда принять.
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
13.10.2009, 14:53
Цитата Сообщение от novi4ok Посмотреть сообщение
приемник подтверждает каждый полученный кусок. если передатчик не получает подтверждения в течение определенного времени, он просто повторяет последний переданный.
Вероятно, имелось в виду "тот кусок, на который не получено подтверждение"? Потому что иначе, например (смотрим пример выше) если не получено подтверждение на кусок 2, а "последний переданный" - кусок 5, то это будет пустая долбежка никому не нужного куска. Можно, конечно же, после каждого переданного куска ждать по таймауту прихода подтверждения именно на него. Но это серьезно снизит скорость передачи - поскольку придется рассчитывать на наихудший случай, передачу через "медленную" сеть, а время таймаута в "медленной" сети может быть намного! больше времени собственно передачи куска. А если не повезет и подтверждение не дойдет (где-то потеряется)? Повторная передача успешно принятого приемником куска и опять таймауты...
Кстати, Lowbacki надо уметь обрабатывать и такой сценарий: переданы куски 12345, на прием они пришли в порядке 13425 - ибо в сетях со сложной топологией датаграммы могут путешествовать по извилистым путям, в т.ч. с существенно разным временем доставки от передатчика к приемнику.
А, например, такой сценарий: передаем 12345, прием: 1325 (кусок 2 пришел позже 3, кусок 4 потерян) ?
0
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
13.10.2009, 16:06
Цитата Сообщение от CheshireCat Посмотреть сообщение
Вероятно, имелось в виду "тот кусок, на который не получено подтверждение"? Потому что иначе, например (смотрим пример выше) если не получено подтверждение на кусок 2, а "последний переданный" - кусок 5, то это будет пустая долбежка никому не нужного куска. Можно, конечно же, после каждого переданного куска ждать по таймауту прихода подтверждения именно на него.
именно так и было сделано.

Добавлено через 3 минуты
Цитата Сообщение от Lowbacki Посмотреть сообщение
Сам определяю (пишу и клиент, и сервер). Сценарии... Не совсем понял. Просто хочу написать две функции Send и Recv. Первая гарантировано отправляет сообщение, а вторая принимает его соответствующим образом.


И сервер, и клиент будут использовать функции и Send, и Recv, но они только "говорят" что отправить или куда принять.
в принципе вопрос "гарантированности" стоит даже если не требуется дробить сообщения. при udp гарантировать доставку возможно только если:
- пользовательский протокол предусматривает подтверждение каждого переданного пакета
- производится сплошная нумерация пакетов. в этом случае, правда, только при получении следующего сообщения известно, было ли доставлено предыдущее. доставка последнего пакета вообще не гарантирована.
0
0 / 0 / 0
Регистрация: 05.10.2009
Сообщений: 27
14.10.2009, 12:06  [ТС]
Кстати, Lowbacki надо уметь обрабатывать и такой сценарий: переданы куски 12345, на прием они пришли в порядке 13425 - ибо в сетях со сложной топологией датаграммы могут путешествовать по извилистым путям, в т.ч. с существенно разным временем доставки от передатчика к приемнику.
А, например, такой сценарий: передаем 12345, прием: 1325 (кусок 2 пришел позже 3, кусок 4 потерян) ?
Для этого каждый переданный пакет будет иметь свой номер и на примеике они будут собиратсья в соответствующем порядке: приём 1325=>123_5 => запрос повтора 4-го

Добавлено через 28 минут
Рассмотрим ситуацию.
1) передатчик будет отправлять функцией sendto(buf, buflen,...) части своего сообщения длиной, например, buflen==1500байт.
2) По ходу доставки на приемник отправленный с передатчика один udp-пакет разобьётся например на 4 пакета

Какие возможны варианты на приемнике? В том смысле, что надо ли приемнику учитывать возможное дробление пакета по пути? Или переданный пакет (те самые 1500байт) либо придёт, либо не придёт?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.10.2009, 12:06
Помогаю со студенческими работами здесь

winsock2
Помогите, вот код: if(WSAConnect(sock, (SOCKADDR*)&addr, sizeof(addr))) { cout << "Connected!"; ...

winsock2.h
Компилирую обычный код: #pragma comment(lib, "ws2_32") #include <winsock2.h> int main() { } Ошибки: 1>------...

Книги по winsock2
Здравствуйте! Посоветуйте книги для изучения сетевого программирования (winsock2) на C/C++. А так же интересует вопрос, можно ли будет...

WinSock и WinSock2
Подскажите книги,литературу по winsock и winsock2.Я не совсем новичек но въехать в сокеты немогу

Winsock2 в классе
Решил сделать класс для дальнейшего применения в разных программах вот что получилось: Файл Konnekt.срр #include "stdafx.h" ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru