|
LwIP факт отправки UDP пакета |
|
|
|
Dec 9 2013, 00:10
|
Участник

Группа: Участник
Сообщений: 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); } }
|
|
|
|
|
Dec 9 2013, 07:57
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Golikov A. @ Dec 9 2013, 10:33)  факта отсылки пакета нет и быть не может. Неправда. Я специально проследил порядок выполнения udp_send(). Он ведёт прямиком к netif->linkoutput, то есть непосредственно к функции отправки пакета драйвером. Естественно, при условии, что arp уже сделал свои дела. Понятно, что драйвер может буферизировать пакеты перед отправкой, но не обязательно. У меня, к примеру, не буферизирует, а сразу отправляет.
|
|
|
|
|
Dec 9 2013, 08:53
|
Участник

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

|
Цитата(scifi @ Dec 9 2013, 10:07)  Я бы проверял возвращаемое значение функции udp_send(). Пробовал. Не помогает. Она на каждый вызов отвечает ОК. А пакеты выходят через один. С задержкой теряются, но 1 из 1000.
|
|
|
|
|
Dec 9 2013, 09:53
|
Участник

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

|
Ну приемное приложение у меня самописное и корявое, но 80-90Мбит\с принимает. В каждый пакет пихаю номер и инкрементирую. Без задержки почти сплошняком теряется каждый второй пакет. Поток при этом тот-же 80-90. А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется.
|
|
|
|
|
Dec 9 2013, 10:26
|
Гуру
     
Группа: Свой
Сообщений: 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() );
это же элементарно, Ватсон. Единствено что в армах это индекс управляющей структуры Это правда элементарно
|
|
|
|
|
Dec 9 2013, 11:05
|
Участник

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

|
Цитата(megajohn @ Dec 9 2013, 14:14)  > А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется. это как так: увеличили период отправки а поток не изменился ? А чего ему меняться, если у нас канал 100Мбит. А я от него больше пытаюсь выжать. вот пакеты и исчезают. А с задержкой как раз 100 и выходит. Цитата(Golikov A. @ Dec 9 2013, 14:26)  надо шарком проверить, есть ли на интерфейсе те пакеты что не дошли до приложения... Если бы каждый потерянный пакет до интерфейса доходил, то поток был бы сильно за сотню. а он и так около 90, при том что примерно половины пакетов нет. Но шарк запущу. А вдруг.....
|
|
|
|
|
Dec 9 2013, 14:15
|
Гуру
     
Группа: Свой
Сообщений: 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 (скажем, через глобальные переменные). Некрасиво, но можно попробовать.
|
|
|
|
|
Dec 9 2013, 15:33
|
Участник

Группа: Участник
Сообщений: 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 собирать информацию ... Некрасиво, но можно попробовать. очень не хочется...но возможно это будет самый простой вариант.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|