потеря UDP пакетов при сильной загрузке ЦП или приложения
От: black_jesus  
Дата: 15.11.05 20:18
Оценка:
Доброе время суток, уважаемые. Заранее извиняюсь,что повторяю уже ранее заданный вопрос, но я так и не нашел объяснения.
Пишу графическое приложение реального времени, работающее на нескольких машинах. Приложение-мастер (сервер) получает по TCP-сокетам данные с частотой примерно 100 Гц по 100 — 150 байт в посылке и должно синхронно ретранслировать данные еще на ряд клиентских машин. Ретрансляция реализована на UDP с помощью multicast. Все нормально работает и ничего не теряется (проверено), но иногда на сервер поступают дополнительные данные, несколько посылок тоже по 100 – 150 байт, которые тоже должны быть ретранслированы клиентам. Так вот в процессе ретрансляции этих посылок часть из них теряется. Заметив такое поведение решил написать отдельный тест и набрел на проблему, подобные которой неоднократно всплывали на этом форуме, но для себя я ответов так и не нашел. А проблема – потеря пакетов в зависимости от занятости приложения или нагрузки процессора.
Проиллюстрирую на примере тестового приложения. Приложение создает два блокирующих UDP сокета (через socket()), один на чтение, другой на запись, запускает поток, в котором для сокета чтения в цикле выполняется recvfrom(), в то время как, в основном потоке для сокета записи в цикле выполняется посылка данных с помощью sendto() (5 байт). На другой машине это же приложение принимает посылки и отправляет обратно подтверждение доставки (5 байт, все посылки нумеруются). Приложение продолжает непрерывно посылать посылки с одним и тем же номером пока не придет подтверждение доставки этой посылки, после чего приложение переходит к отправке следующей посылки и т.д. Если в основном потоке, который шлет посылки после отправки поставить задержку от 6 мс и более, через вызов Sleep(), то все работает чудесно. Если же задержка меньше 6 мс то посылки, примерно каждая 10-ая или около того, начинают теряться (на том конце приложение их не получает и, соответственно, не отправляет подтверждение). Все это происходит при том, что sendto() не возвращает ошибок, а говорит, что все байты посланы. При полном отсутствии задержки в цикле отправки посылок сообщения отправляются, но на другом конце не получаются вообще. Вот такая история. О железе: Dual Core Athlon 64 4800+ CPU, 2 Gb RAM, 1 Gb LAN. ОС Windows XP PRO SP2, сеть более менее в порядке, так как машины включены в отдельный свич, провода метровой длины и больше там никого нет. Сами понимаете, что при таких размерах посылок сеть не грузится более чем на доли процента. Пробовал менять размеры буферов чтения и записи, проверял максимальный размер посылки (SO_RCVBUF, SO_SNDBUF, SO_MAX_MSG_SIZE) – серьезного влияния не оказывают.
Складывается ощущение, что физически пакеты передаются, но не обрабатываются операционной системой. Большая просьба к специалистам, подскажите в чем причина и, если кто знает, то как обойти проблему.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.