Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.79/34: Рейтинг темы: голосов - 34, средняя оценка - 4.79
4 / 4 / 1
Регистрация: 10.07.2011
Сообщений: 52

Задержка пакетов UDP

14.11.2013, 15:34. Показов 6910. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем добрый день,
не нашёл на просторах интернета ответа на свой
вопрос, по этому хочу спросить у вас, надеюсь на ответ.

Принимаю данные по UDP от устройства - самопальной видеокамеры.
Данные отправляются непрерывно, но на стационарных ПК задержка
на приёме минимальная, а вот на ноутбуках Samsung (а возможно и на других)
возникает задержка больше 1 секунды.
Ещё раз раз поясню: устройство отправляет данные в момент Т, а на экране
монитора они отбражаются на стационарном ПК через Т+100мс, а на ноутбуках
через Т+1000мс. Задержка не меняется от времени примерно стабильная.

Принимает ПО на C#, следующим образом:

C#
1
2
3
4
5
6
7
8
9
                int nInData = 0x00;
                int nNetData = UDPClient.Available;
 
                while ((!BreakThread) & (nNetData > 1024) & (pos < (receiveBytes.Length - 1024*1024)))
                    {
                        nInData = UDPClient.Receive(receiveBytes, pos, 1024, SocketFlags.None);
                        nNetData -= 1024;
                        pos += nInData;
                    }
Кстати, забирать из UDPClient кусками больше 1024 не получается, просто не принимает и зависает...
по этому выбираю в цикле кусками по 1024 байта...

Загрузка ПК ПО не более 20%.
Поток данных не более 12Мбайт/с.
Буфер задан, как :
C#
1
2
3
            int BufferSize = 1280 * 1024 * 8 * 16; 
                UDPClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                UDPClient.ReceiveBufferSize = BufferSize;
Что примерно соответствует 160Мбайтам, то есть заведомо больше времени лага...
кажется что и не причём...
Потери пакетов нет, пропусков данных так же нет.
Антивирусы отключены
сетевые карты как на стационарном так и на ноутбуке Realtek GigE

Ну собственно сабж, прошу помощи...

Заранее спасибо!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.11.2013, 15:34
Ответы с готовыми решениями:

Сниффер UDP пакетов
Здравствуйте, нужно написать сниффер, который будет перехватывать только UDP пакеты Начал искать информацию, так понял, что нужно...

Отправка udp sip пакетов .NET 4.5
Возникла проблема, что при попытке отправить SIP сообщения в UDP пакете, SIP часть отправляется как data, в котором просто содержится...

Прием широковещательных UDP пакетов
Делаю следующим образом: public static void ReceiveFrom1() { Socket sock = new...

6
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
18.11.2013, 08:41
Тут дело не в загрузке ПО ПК, а скорее всего в видеокарте ноута, при прочих равных ноут всегда уступает стационарному ПК в производительности
1
4 / 4 / 1
Регистрация: 10.07.2011
Сообщений: 52
21.11.2013, 10:42  [ТС]
Всем привет!
опять же проблема оказалась в реализации StopWatch
(((
может быть кто-то знает как гарантированно измерить
абсолютное время?.
Объясню подробнее, я с помощью StopWatch измеряю интервал
времени равный 35мс, с запасом от 40мс, что соответствует 25Гц,
камера четко со стабильностью 10^-4 выдаёт именно 25Гц видео,
при работе с большинством персональных ПК время измеряется
корректно, буфер не заполняется. При работе с AMD/ATI и вот как оказалось
с ноутом Samsung измеренное время оказывается больше, то есть по факту
не 35мс, а где-то 50мс... буфер переполняется - возникает задержка в буфере.
Опять же повторю вопрос, как измерить абсолютное время в шарпах?...

всем заранее спасибо!
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
21.11.2013, 21:36
Pyhesty, может вы покажете код, как вы используете StopWatch, и мы поищем проблемы в нём. Скорее всего вы что-то делаете не так.
1
4 / 4 / 1
Регистрация: 10.07.2011
Сообщений: 52
21.11.2013, 22:27  [ТС]
спасибо!)
собственно юзаю вот так:
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
26
27
28
       
 public ConcurrentQueue<sFrame> FrameBuffer;
 private void Parse()
        {
            BreakThread = false;
            sFrame Frame;
            Stopwatch swBuf = new Stopwatch();
            swBuf.Start();
            while (!BreakThread) // && !TimeOut)
            {
                if (FrameBuffer != null)
                {
                    int BuffCount = FrameBuffer.Count;
                    long delay = swBuf.ElapsedMilliseconds;
                    if (((BuffCount > VideoBufferSize) && (delay > 35)) || ((BuffCount > 0) && (delay > 45)))
                        if (FrameBuffer.TryDequeue(out Frame))
                        {
                            swBuf.Restart();
                          //  if (writelog) log.WriteLine("Delay time: " + delay + "  " + BuffCount);
                            DrawFrame(ref Frame);
                            nFrame++;
                        }
                        else  Thread.Sleep(1);
                } else 
                    Thread.Sleep(1);
            }
                
        }
Идея предельно просто - создаётся поток, который мониторит FIFO буферов
кадров FrameBuffer, если в нём есть кадры, и время прошло больше 45мс, то в любом случае
выводим кадр, если время прошло от 35 до 45мс и в буфере есть некоторое количество кадров
больше VideoBufferSize, то так же выводим кадр. В буфере необходимо держать несколько кадров,
на случай лагов сети.
C#
1
  if (writelog) log.WriteLine("Delay time: " + delay + "  " + BuffCount);
позволяет вывести лог и построить диаграмму, на нормальном ПК отклонение в выводе изображения
не превышает 5мс. Если же встречается AMD или такой ноутбук, что у меня, то получается,
что ПК думает, что времени прошло меньше чем нужно и буфер начинает переполнятся,
тк всегда срабатывает условие, ((BuffCount > VideoBufferSize) && (delay > 35)), при том, что
буфер полностью заполнен...
Кадры поступают гарантированно раз в 40мс... Предполагаю, что незаметно для программы
меняется частота процессора и StopWatch не меняет некоторую переменную типа CPU_TICKS.
При этом на своём ПК, запускаю CPU-Z и наблюдаю, что тактовая процессора меняется от 1.6ГГц, до 3.0
и это не сказывается на работе ПО, почему это сказывается на других процессорах, не могу понять.
Прошу помощи, заранее спасибо!
0
0 / 0 / 0
Регистрация: 18.09.2015
Сообщений: 1
16.11.2016, 12:29
та же проблема - не могу обработать звук входящий из УДП вовремя. пакеты приходят со скоростью 30мс, а я их получаю с помощью UDPClient.Receive со скоростью за 100мс и больше, при этом весть остальной код уже давно выключен - тормозит сам класс UDPClient!!!

буду искать ответы, другого выбора у меня нет!
0
1152 / 860 / 263
Регистрация: 30.04.2009
Сообщений: 3,603
26.11.2016, 10:30
При выполнении Thread.Sleep(x) поток отказывается от выделенного ему кванта времени и сможет продолжить работу не раньше чем при следующем запуске системного таймера (Windows system timer).
По умолчанию период системного таймера (timer resolution) равняется 15.6 ms. Но программы могут уменьшать это значение до 1 ms и даже до 0.5 ms.
Поэтому ваша проблема воспроизводится не на всех компьютерах, а только на тех, где этот таймер не установлен на меньший период.
В случае стандартного периода 15.6 ms несмотря на все ваши стремления (Thread.Sleep(1)) значения delay будут в основном такими: 0->15.6 (16)->31.2 (31)->46.8 (47).
А учитывая, что Stopwatch перезапускается после обработки каждого кадра, то ошибка будет постоянно накапливаться.
Самый простой вариант - это установить интервал системного таймера в 1 ms, тогда вся эта колбасня со Thread.Sleep(1) будет работать как положено, с квантованием в 1 ms.
Но я бы попробовал переделать обработку кадров на использование высокоточного WinApi таймера. Средняя частота вызова события этого таймера будет гарантировано 40 ms.

C#
1
2
3
4
5
6
7
            AccurateTimer t = new AccurateTimer(40);
            t.TimerTick += (s, e) =>
            {
                // поместить сюда обработку кадра
            };
 
            t.Start(); // t.Stop() обязательно нужно вызвать при закрытии программы, или когда таймер больше не нужен
Реализация таймера:
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
  public class AccurateTimer
    {
        private delegate void TimerEventDel(int id, int msg, IntPtr user, int dw1, int dw2);
        private const int TIME_PERIODIC = 1;
        private const int EVENT_TYPE = TIME_PERIODIC;
        [DllImport("winmm.dll")]
        private static extern int timeBeginPeriod(int msec);
        [DllImport("winmm.dll")]
        private static extern int timeEndPeriod(int msec);
        [DllImport("winmm.dll")]
        private static extern int timeSetEvent(int delay, int resolution, TimerEventDel handler, IntPtr user, int eventType);
        [DllImport("winmm.dll")]
        private static extern int timeKillEvent(int id);
 
        private int mTimerId;
        private TimerEventDel mHandler;  // NOTE: declare at class scope so garbage collector doesn't release it
 
        public event EventHandler TimerTick;
        private int _interval;
        
        public AccurateTimer(int interval)
        {
            _interval = interval;
        }
 
        public void Start()
        {
            if (mHandler != null)
            {
                throw new InvalidOperationException("Timer have been already started");
            }
 
            timeBeginPeriod(1);
            mHandler = new TimerEventDel(TimerCallback);
            mTimerId = timeSetEvent(_interval, 0, mHandler, IntPtr.Zero, EVENT_TYPE);
        }
 
        public void Stop()
        {
            int err = timeKillEvent(mTimerId);
            timeEndPeriod(1);
            System.Threading.Thread.Sleep(100);// Ensure callbacks are drained
        }
        
        private void TimerCallback(int id, int msg, IntPtr user, int dw1, int dw2)
        {
            var h = TimerTick;
            if (h != null)
            {
                h(this, EventArgs.Empty);
            }
        }
    }
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.11.2016, 10:30
Помогаю со студенческими работами здесь

Прием пакетов по UDP
Приветствую. С сетевыми протоколами раньше дела не имел. Начал сразу к практике приступать. Хотел посмотреть, как вообще реализовать...

Потери UDP пакетов
Всем привет. Моя работа заключается в настройке IP_TV. Довольно часто люди жалуются на зависание картинки. Хотелось бы узнать побольше...

Перехват UDP пакетов
Здравствуйте ! Есть два комп'ютера связанные по сети. Программа на первом отправляет некие данные на второй по UDP протоколу. Как...

Потери UDP пакетов
Всем здравствуйте...Столкнулся со следующей проблемой. Попытался передать довольно большой файл по сети UDP пакетами размером в пару сотен...

Прием UDP пакетов
Здравствуйте. Сразу скажу, никогда не имел дело с сокетами, тем более с UDP. Сервер у меня на python и с ним проблем никаких нет, клиент...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru