Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/25: Рейтинг темы: голосов - 25, средняя оценка - 4.92
 Аватар для SAkonst
2 / 2 / 0
Регистрация: 11.02.2012
Сообщений: 19

Передача большого объема данных по UDP

29.08.2014, 12:32. Показов 5038. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, форумчане!

Возникла у меня необходимость передавать большой объем данных по UDP.
sendto() посылает буфер частями по 65507 байт. Если под конец буфера остается меньше, то то что осталось соответственно.
recvfrom() принимает принимает в буфер такого же размера эти части.
И все вроде бы ничего, но столкнулся с такой проблемой:

Когда приходит последняя часть (которая меньше, чем 65507) recvfrom() возвращает WSAEMSGSIZE, хотя в буфере должно еще было остаться место. (причем ровно столько сколько отослал sendto).

На примере это выглядит так:
Необходимо послать 1806528 байт.
sendto() посылает 65507 из этого. ()
recvfrom() принимает 65507 и заполняет буфер. В буфере остается 1806528 - 65007 == 1741021 Все честно.
И так далее.
Когда оставшаяся часть, которую надо послать становится меньше 65507, то sendto() отсылает остаток. В данном случае 37839.
так как recvfrom() заполнял буфер постоянно известными частями по 65507 байт то в буфере под конец останется 37839. Все сходится.
Но не тут то было! А именно когда в буфере остается 1768689 (а это 1806528 - 37839), именно в тот момент когда все сходится с точностью до байта - recvfrom() возвращает WSAEMSGSIZE.
Все никак не могу понять откуда такая проблема.

Вот код:
Client
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//инициализация сокета
sockaddr_in addr;
 
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(IP);
addr.sin_port = htons(port);
 
//цикл передачи
int permitmsgsize;
int optlen = sizeof(optlen);
int slen = sizeof(addr);
int sendsize = 0;
int ss = 0;
 
getsockopt(sock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*)&permitmsgsize, &optlen);
while (ss != MsgSize) // MsgSize заранее известен
{
    if (MsgSize - ss > permitmsgsize)
        sendsize = permitmsgsize;
    else sendsize = MsgSize - ss;
        
    res = sendto(sock, (char*)msg + ss, sendsize, 0, (struct sockaddr *) &addr, slen);
    ss += sendsize;
}
Server:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//инициализация сокета
sockaddr_in si;
int slen = sizeof(si);
addrinfo addrinf;
addrinfo addrresult;
si.ai_family = AF_INET;
si.ai_flags = AI_PASSIVE;
si.ai_socktype = SOCK_DGRAM;
si.ai_protocol = IPPROTO_UDP;
 
res = getaddrinfo(NULL, (PCSTR)Port, &si, &addrresult);
socket(addrresult->ai_family, addrresult->ai_socktype, addrresult->ai_protocol);
bind(ListenSocket, addrresult->ai_addr, (int)addrresult->ai_addrlen);
 
//цикл приема
while (recvbytes != size) //size заранее известен и равен MsgSize из Client.
     recvfrom(ListenSocket, Buffer + recvbytes, size - recvbytes, NULL, (struct sockaddr *)&si, &slen);
В дополнение. Проблема исчезает когда я после каждого sendto() ставлю Sleep(20); Но это не дело, конечно. Неужели recvfrom так медленно работает. И даже если и так, то ну забьется у него стек сетевой - все-равно же будет брать.
Есть ли у вас какие-нибудь мысли по этому поводу? Буду очень признателен и заранее благодарен.

P.S старался как можно более развернуто описать поэтому извините за "многабукаф")).

Добавлено через 39 минут
Прошу прощения. В цикле приема, конечно же должна быть инкрементация:
C++
1
2
3
4
5
6
while (recvbytes != size) //size заранее известен и равен MsgSize из Client.
{
     res = recvfrom(ListenSocket, Buffer + recvbytes, size - recvbytes, NULL, (struct sockaddr *)&si, 
     recvbytes += res;
}
Не все выдернул из кода)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.08.2014, 12:32
Ответы с готовыми решениями:

Размер запроса GET, передача большого объема параметров в нем
Добрый день! У меня возникли вопросы в процессе работы, в очередной раз прошу помощи специалистов в области веб программирования... 1....

Проверка большого объема данных
Мне надо проверить паспортные данные на правильность, что то на подобии что первые 4 цифры, это серия и именно цифры, и номер именно 6...

Чтение большого объема данных
Доброго времени суток. У меня есть файлик (.тхт), в нем очень много числовых значений, которые мне нужны для анализа данных (не важно...

6
И целого heap'а мало
 Аватар для Andrej
96 / 57 / 17
Регистрация: 31.07.2014
Сообщений: 291
01.09.2014, 23:42
memset(), таки надо подчищать.
О, ещё попробуй уменьшить посылаемый кусок, MTU же.
1
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
02.09.2014, 11:31
SAkonst, ошибка свидетельствует о том что забился буфер, что подтверждает отсутствие ошибки если sendto выполняется медленнее(со слипом)

Добавлено через 3 минуты
и кстати, а на принимающей стороне Вы уверены что размер буфера такой же что и на передающей?
0
 Аватар для SAkonst
2 / 2 / 0
Регистрация: 11.02.2012
Сообщений: 19
02.09.2014, 13:36  [ТС]
Andrej, Хм. Спасибо. про MTU я не подумал. Возможно имеет даже смысл посылать кусок кратный 16 для выравнивания. Спасибо за идею. Опробую.
aLarman, Так в том все и дело, что уверен. Информацию о картинке я передаю еще до передачи самой картинки. И она доходит отлично. Вы имеете ввиду, что забивается буфер на принимающей стороне? Т. е. действительно recvfrom() работает сильно медленее sendto() и не успевает все "разгрести"?
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
02.09.2014, 13:48
Цитата Сообщение от SAkonst Посмотреть сообщение
и не успевает все "разгрести"?
cудя по всему да, Вы же сами говорите, если передачу замедлить, то все норм

Добавлено через 10 минут
Цитата Сообщение от SAkonst Посмотреть сообщение
Информацию о картинке я передаю еще до передачи самой картинки.
не путаете программный буфер для картинки и буфер сетевой, нельзя же закинуть в сокет кучу инфы, достигнется какой то предел, и далее инфа будет отбрасываться
1
 Аватар для SAkonst
2 / 2 / 0
Регистрация: 11.02.2012
Сообщений: 19
02.09.2014, 14:55  [ТС]
aLarman, Логично)). Благодарю за информацию к размышлению. Теперь я представляю куда копать. Если получится оттестировать - обязательно отпишусь.
0
0 / 0 / 0
Регистрация: 11.08.2016
Сообщений: 19
12.08.2016, 00:33
у вас в сервере проблема с si.
там совсем другие поля в структуре.
это компилируется ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.08.2016, 00:33
Помогаю со студенческими работами здесь

Обработка большого объема данных
Добрый ночи ребята помогите с одной проблемой. У на старом сайте одного проекта есть база в которой находятся больше 5 000 записей (+...

Люди! Помогите разобраться с записью большого объема данных в поле с типом данных text
Дело в том, что мне нужно записать в поле с типом text XML-документ. Но проблема состоит в том, что этот XML может быть оч. большого...

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

Добавление большого объема данных в mysql
Здравствуйте! Мне нужно добавить большой объем текста в mysql через обычное поле input типа file в php. Постоянно когда я запускай...

Обработка большого объема данных (теги сайта)
Есть сайт, у него таблица tags 207,168 штук MyISAM utf8_general_ci 16 МБ весом =) нужно их обработать Под...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
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
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru