Перейти к содержанию
    

LwIP факт отправки UDP пакета

Отсылаю больщой объем данных по UDP. Пакетами по 1000 байт. Не могу понять, как определить, готов стек к приему нового пакета или нет. Сейчас похоже слишком часто вызываю udp_send() и поэтому каждый второй пакет не доходит. Задержка помогает, но не всегда.

while (1)
      {
        /* check if any packet received */
        if (ETH_CheckFrameReceived())
        {
          /* process received ethernet packet */
          LwIP_Pkt_Handle();
        }
        /* handle periodic timers for LwIP */
        LwIP_Periodic_Handle(LocalTime);
            get_new_data(data);  //получаю данные
            //delay(); //Задержка
        /* allocate pbuf from pool*/
            p = pbuf_alloc(PBUF_TRANSPORT, 1000, PBUF_POOL);
        if (p != NULL ) {
            /* copy data to pbuf */
            pbuf_take(p, (char*) data, 1000);
            /* send udp data */
            udp_send(upcb, p);
            /* free pbuf */
            pbuf_free(p);
        }
      }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

факта отсылки пакета нет и быть не может.

Единственное что вы можете получить это то что на него выделен буфер и он добавлен в очередь отправки, а отправка произойдет во время обработки основной функции стэка. А также учитывая что UDP пакетный, а не потоковый, напихав много пакетов уходить они будут по очереди с каждым новым вызовом этой функции

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

факта отсылки пакета нет и быть не может.

Неправда. Я специально проследил порядок выполнения udp_send(). Он ведёт прямиком к netif->linkoutput, то есть непосредственно к функции отправки пакета драйвером. Естественно, при условии, что arp уже сделал свои дела. Понятно, что драйвер может буферизировать пакеты перед отправкой, но не обязательно. У меня, к примеру, не буферизирует, а сразу отправляет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы проверял возвращаемое значение функции udp_send().
Пробовал. Не помогает. Она на каждый вызов отвечает ОК. А пакеты выходят через один. С задержкой теряются, но 1 из 1000.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"буферизируются или нет", это называются Блокирующие ( синхронные ) или неблокирующие ( ассинхронные ) сокеты =)

 

обычно задается на этапе компиляции или же при создании сокета ( если правда поддерживается стеком )

так что поищите в настройках lwIP

 

и кстати, "теряются" вы судите по приемной стороне или по WireShark ?

 

если приемная сторона не успевает обрабатывать, то это проблема никак не относится к передающей стороне. На то он и UDP

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну приемное приложение у меня самописное и корявое, но 80-90Мбит\с принимает. В каждый пакет пихаю номер и инкрементирую. Без задержки почти сплошняком теряется каждый второй пакет. Поток при этом тот-же 80-90. А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

блокирующий и не блокирующий - это разве не к операционке относится? LwIP может и без нее фигачить...

 

сейчас поглядел на UDP посылку, вызывая целую кучу функций одну за другой походу дела склеивает пакеты, добавляет заголовки, а потом правда пихает это все прямиком на выход. Как то я упустил этот момент, извиняюсь, правда обманул.

 

Другое дело что по ходу этих функций есть кучу мест на которых процесс может прерваться и оно все вывалиться, но вываливается оно с кодами ошибок и отладочными сообщениями. Даже последняя функция выдачи наружу тоже возвращает код ошибки.

 

Так что если send_UDP вернуло ок, то до драйвера сообщение дошло, и наверняка во все буферы (если они дальше есть) добавилось и до выхода дойдет.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

> А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется.

это как так: увеличили период отправки а поток не изменился ?

 

>блокирующий и не блокирующий - это разве не к операционке относится?

операционка задат лишь приоритет задач, и их переключение. А ждать завершения отправки по физическому каналу это уже другое

 

на пальцах:

*data_reg = 'a'; *data_reg = 'b';

или

*data_reg = 'a'; while( data_reg_busy() ); *DATA_REG = 'b'; while( data_reg_busy() );

 

это же элементарно, Ватсон. Единствено что в армах это индекс управляющей структуры

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну приемное приложение у меня самописное и корявое, но 80-90Мбит\с принимает. В каждый пакет пихаю номер и инкрементирую. Без задержки почти сплошняком теряется каждый второй пакет. Поток при этом тот-же 80-90. А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется.

 

надо шарком проверить, есть ли на интерфейсе те пакеты что не дошли до приложения...

 

на пальцах:

*data_reg = 'a'; *data_reg = 'b';

или

*data_reg = 'a'; while( data_reg_busy() ); *DATA_REG = 'b'; while( data_reg_busy() );

 

это же элементарно, Ватсон. Единствено что в армах это индекс управляющей структуры

 

Это правда элементарно

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

> А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется.

это как так: увеличили период отправки а поток не изменился ?

А чего ему меняться, если у нас канал 100Мбит. А я от него больше пытаюсь выжать. вот пакеты и исчезают. А с задержкой как раз 100 и выходит.

 

 

надо шарком проверить, есть ли на интерфейсе те пакеты что не дошли до приложения...

Если бы каждый потерянный пакет до интерфейса доходил, то поток был бы сильно за сотню. а он и так около 90, при том что примерно половины пакетов нет.

Но шарк запущу. А вдруг.....

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А чего ему меняться, если у нас канал 100Мбит.

 

я бы назвал это пропускной способностью. А поток это уже ваши данные.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

то есть задача стоит как ограничить свои данные на выход, чтобы не засрать канал?

 

ну если не ТСР, то надо добавить контроль потока в УДП. Подтверждать получение, фактически перейти на ТСР...

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"буферизируются или нет", это называются Блокирующие ( синхронные ) или неблокирующие ( ассинхронные ) сокеты =)

Знаете, что такое "lwip raw API", pbuf_alloc() и udp_send()? Там сокетами и не пахнет.

 

то есть задача стоит как ограничить свои данные на выход, чтобы не засрать канал?

ну если не ТСР, то надо добавить контроль потока в УДП. Подтверждать получение, фактически перейти на ТСР...

Не обязательно. Можно на уровне Ethernet MAC собирать информацию (пакет ушёл или не ушёл) и передавать в приложение. Это можно делать в обход lwip (скажем, через глобальные переменные). Некрасиво, но можно попробовать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Запустил шарк. 45 000 пакетов принято. А счетчик пакетов (первые 4 байта пакета)70 000. Как-то так....

 

    
while (1) {
    /* check if any packet received */
        if (ETH_CheckFrameReceived()) {
    /* process received ethernet packet */
         LwIP_Pkt_Handle();
    }
    /* handle periodic timers for LwIP */
    LwIP_Periodic_Handle(LocalTime);
    /* allocate pbuf from pool*/
    p = pbuf_alloc(PBUF_TRANSPORT, 1000, PBUF_POOL);
    if (p != NULL) {
        /* copy data to pbuf */
        pbuf_take(p, (char*) data, 1000);
        /* send udp data */
        if (udp_send(upcb, p) == ERR_OK) {
            PacketCount++;
                        data[0] = (PacketCount >> 24) & 0x000000FF;
            data[1] = (PacketCount >> 16) & 0x000000FF;
            data[2] = (PacketCount >> 8) & 0x000000FF;
            data[3] = (PacketCount) & 0x000000FF;
            //Delay_xx(500);
        }
    /* free pbuf */
    pbuf_free(p);
    }
}

 

 

Можно на уровне Ethernet MAC собирать информацию ... Некрасиво, но можно попробовать.

очень не хочется...но возможно это будет самый простой вариант.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...