![]() |
Модераторы: feodorv |
![]() ![]() ![]() |
|
semibug |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 27.3.2009 Репутация: нет Всего: нет |
Имеется UDP сервер, в цикле выгребающий пакеты из сокета и обрабатывающий их. Время обработки может варьироваться. Интересует организация очереди входящих UDP дейтаграмм в Windows ( XP SP 3):
- размер очереди (в байтах / в UDP дейтаграммах), есть ли возможность повлиять - что произойдет если очередь переполнится: самый старый пакет (или несколько, смотря сколько необходимо выделить места) удаляется и новый помещается в конец очереди, либо новые пакеты отбрасываются. Это сообщение отредактировал(а) semibug - 29.5.2009, 02:05 |
|||
|
||||
semibug |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 27.3.2009 Репутация: нет Всего: нет |
Вот такие наблюдения на локальном хосте:
(для тестов использовал две простые програмки - сначала одна отправляет нужное кол-во UDP дейтаграм, затем вторая, по нажатию кнопки выгребает их из сокета). - если во входящей очереди уже 8192 (8 килобайт) и более данных, новые пакеты отбрасываются. - если во входящей очереди менее 8192 байт, то сокет в состоянии принять UDP дейтаграмму размером до 65507 байт. Считывая UDP дейтаграммы из сокета, мы освобождаем место под новые. Тесты проводились под WindowXP SP3, для localhost, без каких либо специальных настроек сетевой подсистемы. |
|||
|
||||
MaXL |
|
|||
![]() Developer ![]() ![]() Профиль Группа: Участник Сообщений: 380 Регистрация: 24.10.2005 Где: Владивосток Репутация: нет Всего: 2 |
semibug, а не удалось выяснить ответ на вопрос ?
-------------------- MaXL |
|||
|
||||
Олег2005 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 421 Регистрация: 26.5.2005 Где: Рига Латвия Репутация: 6 Всего: 11 |
Это - общие положения для буферов UDP:
В случае протокола UDP пакет, не помещающийся в приемный буфера сокета, игнорируется, т.е. просто не обрабатывается. Ведь в UDP отсутствует управление потоком, и более скоростной отправитель легко подавит более медленного получателя, заставляя модуль UDP получателя игнорировать дейтаграммы. Поэтому для приемного буфера UDP надо по возможности выделять большие объемы памяти. Как уже говорилось, опции SO_RCVBUF и SO_SNDBUF позволяют приложению изменять размеры буферов, заданные по умолчанию, которые для различных реализаций очень отличаются. В Беркли-реализациях по умолчанию используются буфера отправки и приема размером в 4096 байт, более современные системы используют буфера размером от 8192 до 61 440 байт. Размер буфера отправки UDP по умолчанию обычно около 9000 байт, если узел поддерживает NFS; а размер приемного буфера UDP — около 40 000 байт, а максимальное значение по умолчанию может достигать и 250Кб. Cтивенс: 20.3. Обрезанные дейтаграммы Пример из предыдущего раздела показывает, что когда в BSD/OS приходит дейтаграмма UDP, размер которой больше буфера приложения, функция recvmsg устанавливает флаг MSG_TRUNC в элементе msg_flags структуры msghdr (см. табл. 13.2). Все Беркли-реализации, поддерживающие структуру msghdr с элементом msg_flags, предоставляют это уведомление. ПРИМЕЧАНИЕ Это пример флага, который должен быть возвращен процессу ядром. В разделе 13.3 мы упомянули о проблеме разработки функций recv и recvfrom: их аргумент flags является целым числом, что позволяет передавать флаги от процесса к ядру, но не наоборот. К сожалению, не все реализации подобным образом обрабатывают ситуацию, когда размер дейтаграммы UDP оказывается больше, чем предполагалось. Возможны три сценария: 1. Лишние байты игнорируются, и приложение получает флаг MSG_TRUNC, что требует вызова функции recvmsg. 2. Игнорирование лишних байтов без уведомления приложения. 3. Сохранение лишних байтов и возвращение их в последующих операциях чтения на сокете. Мы уже видели развитие первого сценария в BSD/OS. Второй тип сценария можно увидеть в Solaris 2.5: лишние байты игнорируются, но поскольку структура msghdr не поддерживает элемента msg_flags, нет возможности возвратить ошибку приложению. ПРИМЕЧАНИЕ Posix. lg задает первый тип поведения: игнорирование лишних байтов и установку флага MSG_TRUNC. Более ранние реализации SVR4 действовали в подобных ситуациях по третьему сценарию. Как ведет себя Виндовс - сие науке неизвестно ![]() Это сообщение отредактировал(а) Олег2005 - 3.6.2009, 17:08 |
|||
|
||||
semibug |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 27.3.2009 Репутация: нет Всего: нет |
С помощью setsockopt удалось выставить размер входного буфера в 1 гигабайт, дальше проверять не стал. int OptVal = 1024 * 64; int OptLen = sizeof( OptLen ); setsockopt( Socket, SOL_SOCKET, SO_RCVBUF, (char*) &OptVal, OptLen ); Чуть менее чем полностью тестил с размером буфера в 64 кб, работает как и ожидалось. С остальными размерами буфера (не считая, видимо, гигантских в несколько гиг) видимо ситуация аналогичная. |
|||
|
||||
![]() ![]() ![]() |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |