Потеря UDP-пакетов при большой загрузке процессора
От: Basil2 Россия https://starostin.msk.ru
Дата: 08.12.03 14:16
Оценка:
Есть:
UDP-сервер под Windows NT/2000 (написан мной). Сервер — single-thread async, гарантия доставки пакетов обеспечивается перепосылкой пакета до тех пор, пока на него не придет подтверждение от получателя. (подтверждение — тоже UDP-пакет в 20 байт)

Проблема:
При большой загрузке компьютера (например, архивация логов) значительная часть пакетов (иногда — почти все) начинает теряться. Причем из лога сервера видно, что он ОТПРАВЛЯЕТ пакеты как обычно (с той же частотой), но они ПЕРЕСТАЮТ ДОХОДИТЬ до адресата. Клиент продолжает долбиться на сервер с пакетом, не получая отсылаемых сервером подтверждений. При убирании нагрузки пакеты снова начинают проходить нормально. То есть, подытоживая, при большой нагрузке ИСХОДЯЩИЙ UDP-трафик начинает теряться (входящий — в полном порядке).

Вопрос:
Что можно подкрутить в Windows, в программе и в настройках сокета, чтобы уменьшить потерю исходящих UDP-пакетов под нагрузкой?
Какие параметры задать для сокета?


P.S. Например, у меня был размер буферов SNDBUF и RCVBUF по 64Кб — пакеты терялись очень сильно, уменьшил до 4Кб — стало работать гораздо лучше (но все равно потери есть).
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re: Потеря UDP-пакетов при большой загрузке процессора
От: Аноним  
Дата: 08.12.03 16:09
Оценка:
Со 100%-гарантией ничего сделать нельзя.
Потеря пакетов — это документированная особенность UDP.
Re: Потеря UDP-пакетов при большой загрузке процессора
От: butcher Россия http://bu7cher.blogspot.com
Дата: 09.12.03 06:40
Оценка:
Здравствуйте, Basil2, Вы писали:

подними приоритет процесса, тоже немного помогает

Нет ничего невозможного..
Re: Потеря UDP-пакетов при большой загрузке процессора
От: Аноним  
Дата: 09.12.03 10:34
Оценка:
UDP с подтверждением? Орриганально! А как узнать, что подтверждение дошло?
TCP уже написан для этого
Re[2]: Потеря UDP-пакетов при большой загрузке процессора
От: Linuxoid  
Дата: 09.12.03 10:45
Оценка:
Здравствуйте, Аноним, Вы писали:


А> А как узнать, что подтверждение дошло?


Элементарно, Ватсон. Если подтверждение не дошло, тебя перезапросят.
Re[2]: Потеря UDP-пакетов при большой загрузке процессора
От: Basil2 Россия https://starostin.msk.ru
Дата: 09.12.03 11:54
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Со 100%-гарантией ничего сделать нельзя.

А>Потеря пакетов — это документированная особенность UDP.
А то я не знаю. Я ж специально про подтверждения написал — показать действия программы в случае потери пакетов.

Вопрос — как можно УМЕНЬШИТЬ потери пакетов?
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[2]: Потеря UDP-пакетов при большой загрузке процессора
От: Basil2 Россия https://starostin.msk.ru
Дата: 09.12.03 12:03
Оценка:
Здравствуйте, Аноним, Вы писали:


А> UDP с подтверждением? Орриганально! А как узнать, что подтверждение дошло?


Реализовано так:
1. Отправитель посылает пакет
2. Получатель, получив пакет, отсылает обратно подтверждение (пакет с тем же заголовком, но без данных и с флагом ACK).
3. Отправитель, получив подтверждение, считает пакет прошедшим. Пока подтверждение не получено, отправитель перепосылает пакет с определенным интервалом.
4. Получатель ведет список номеров полученых пакетов. Если подтверждение потерялось и отправитель прислал пакет повторно, то такой пакет отбрасывается.


А> TCP уже написан для этого

Протокол TCP/IP не подходил во-первых, из-за потоковости (требовались сообщения), а во-вторых (главное) — из-за плохой работы на GPRS (вследствие больших задержек в сети).
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re: Потеря UDP-пакетов при большой загрузке процессора
От: Аноним  
Дата: 09.12.03 14:03
Оценка:
Здравствуйте, Basil2, Вы писали:

[поскипал]
а зачем такой гемор то городить, с перепосылкой и подтверждением? лучьше возьми TCP и собирай TCP поток в пакеты, чем брать UDP и обеспечивать гарантированную доставку
Re: Потеря UDP-пакетов при большой загрузке процессора
От: DOOM Россия  
Дата: 10.12.03 07:36
Оценка:
Здравствуйте, Basil2, Вы писали:

[skipped]

Очень хотелось бы узнать сокеты какие(в смысле блокирующие или нет)?
Если неблокирующие, то необходимо обрабатывать событие FD_WRITE — т.е. событие, что система готова послать следующий пакет.
Re: Потеря UDP-пакетов при большой загрузке процессора
От: sercher Украина  
Дата: 10.12.03 08:44
Оценка:
У меня в UDP генераторе под Win2000, каждую секунду 4 пакета из 1000 просто так пропадало. А под Линукс такого не было. Вывод: винде нельзя доверять не в чём.
Re[2]: Потеря UDP-пакетов при большой загрузке процессора
От: Basil2 Россия https://starostin.msk.ru
Дата: 16.12.03 09:20
Оценка:
Здравствуйте, DOOM, Вы писали:

DOO>Здравствуйте, Basil2, Вы писали:


DOO>[skipped]


DOO>Очень хотелось бы узнать сокеты какие(в смысле блокирующие или нет)?

Неблокирующие, сижу на FD_READ с помощью WaitForMultipleObjects().

DOO>Если неблокирующие, то необходимо обрабатывать событие FD_WRITE — т.е. событие, что система готова послать следующий пакет.

Спасибо за интересную идею, я попробую. Сервер работает по принципу "запрос-ответ", поэтому возникают вопросы:

1. Как проверить готовность сокета на запись? И если только через Select(), то можно ли сделать задержку 0?
2. Не будут ли проверки готовности замедлять работу?
3. Что делать, если сокет не готов, но надо послать ответ? Поставить событие FD_WRITE и ждать WaitForSingleObject?
4. Все операции сервера с sendto() оканчиваются кодом возврата, численно равным кол-ву посланных байт. Можно ли на этой основе сделать вывод, что сокет всегда готов к записи?
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.