реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> LwIP факт отправки UDP пакета
Real_Bastard
сообщение Dec 9 2013, 00:10
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 7-11-06
Из: Санкт-Петербург
Пользователь №: 22 041



Отсылаю больщой объем данных по 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);
        }
      }
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 9 2013, 06:07
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Я бы проверял возвращаемое значение функции udp_send().
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Dec 9 2013, 06:33
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



факта отсылки пакета нет и быть не может.
Единственное что вы можете получить это то что на него выделен буфер и он добавлен в очередь отправки, а отправка произойдет во время обработки основной функции стэка. А также учитывая что UDP пакетный, а не потоковый, напихав много пакетов уходить они будут по очереди с каждым новым вызовом этой функции
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 9 2013, 07:57
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Golikov A. @ Dec 9 2013, 10:33) *
факта отсылки пакета нет и быть не может.

Неправда. Я специально проследил порядок выполнения udp_send(). Он ведёт прямиком к netif->linkoutput, то есть непосредственно к функции отправки пакета драйвером. Естественно, при условии, что arp уже сделал свои дела. Понятно, что драйвер может буферизировать пакеты перед отправкой, но не обязательно. У меня, к примеру, не буферизирует, а сразу отправляет.
Go to the top of the page
 
+Quote Post
Real_Bastard
сообщение Dec 9 2013, 08:53
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 7-11-06
Из: Санкт-Петербург
Пользователь №: 22 041



Цитата(scifi @ Dec 9 2013, 10:07) *
Я бы проверял возвращаемое значение функции udp_send().
Пробовал. Не помогает. Она на каждый вызов отвечает ОК. А пакеты выходят через один. С задержкой теряются, но 1 из 1000.
Go to the top of the page
 
+Quote Post
megajohn
сообщение Dec 9 2013, 09:38
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



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

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

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

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


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
Real_Bastard
сообщение Dec 9 2013, 09:53
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 7-11-06
Из: Санкт-Петербург
Пользователь №: 22 041



Ну приемное приложение у меня самописное и корявое, но 80-90Мбит\с принимает. В каждый пакет пихаю номер и инкрементирую. Без задержки почти сплошняком теряется каждый второй пакет. Поток при этом тот-же 80-90. А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Dec 9 2013, 09:56
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



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

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

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

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


Go to the top of the page
 
+Quote Post
megajohn
сообщение Dec 9 2013, 10:14
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



[quote name='Golikov A.' date='Dec 9 2013, 13:56' post='1217234']
> А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется.
это как так: увеличили период отправки а поток не изменился ?

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

на пальцах:
*data_reg = 'a'; *data_reg = 'b';
или
*data_reg = 'a'; while( data_reg_busy() ); *DATA_REG = 'b'; while( data_reg_busy() );

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


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Dec 9 2013, 10:26
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата(Real_Bastard @ Dec 9 2013, 13:53) *
Ну приемное приложение у меня самописное и корявое, но 80-90Мбит\с принимает. В каждый пакет пихаю номер и инкрементирую. Без задержки почти сплошняком теряется каждый второй пакет. Поток при этом тот-же 80-90. А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется.


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

Цитата(megajohn @ Dec 9 2013, 14:14) *
на пальцах:
*data_reg = 'a'; *data_reg = 'b';
или
*data_reg = 'a'; while( data_reg_busy() ); *DATA_REG = 'b'; while( data_reg_busy() );

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


Это правда элементарно
Go to the top of the page
 
+Quote Post
Real_Bastard
сообщение Dec 9 2013, 11:05
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 7-11-06
Из: Санкт-Петербург
Пользователь №: 22 041



Цитата(megajohn @ Dec 9 2013, 14:14) *
> А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется.
это как так: увеличили период отправки а поток не изменился ?
А чего ему меняться, если у нас канал 100Мбит. А я от него больше пытаюсь выжать. вот пакеты и исчезают. А с задержкой как раз 100 и выходит.


Цитата(Golikov A. @ Dec 9 2013, 14:26) *
надо шарком проверить, есть ли на интерфейсе те пакеты что не дошли до приложения...

Если бы каждый потерянный пакет до интерфейса доходил, то поток был бы сильно за сотню. а он и так около 90, при том что примерно половины пакетов нет.
Но шарк запущу. А вдруг.....
Go to the top of the page
 
+Quote Post
megajohn
сообщение Dec 9 2013, 12:04
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



Цитата(Real_Bastard @ Dec 9 2013, 15:05) *
А чего ему меняться, если у нас канал 100Мбит.


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


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Dec 9 2013, 13:00
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



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

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

Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 9 2013, 14:15
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(megajohn @ Dec 9 2013, 13:38) *
"буферизируются или нет", это называются Блокирующие ( синхронные ) или неблокирующие ( ассинхронные ) сокеты =)

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

Цитата(Golikov A. @ Dec 9 2013, 17:00) *
то есть задача стоит как ограничить свои данные на выход, чтобы не засрать канал?
ну если не ТСР, то надо добавить контроль потока в УДП. Подтверждать получение, фактически перейти на ТСР...

Не обязательно. Можно на уровне Ethernet MAC собирать информацию (пакет ушёл или не ушёл) и передавать в приложение. Это можно делать в обход lwip (скажем, через глобальные переменные). Некрасиво, но можно попробовать.
Go to the top of the page
 
+Quote Post
Real_Bastard
сообщение Dec 9 2013, 15:33
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 7-11-06
Из: Санкт-Петербург
Пользователь №: 22 041



Запустил шарк. 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);
    }
}



Цитата(scifi @ Dec 9 2013, 18:15) *
Можно на уровне Ethernet MAC собирать информацию ... Некрасиво, но можно попробовать.

очень не хочется...но возможно это будет самый простой вариант.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 14th July 2025 - 19:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.01511 секунд с 7
ELECTRONIX ©2004-2016