Real_Bastard 0 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба Отсылаю больщой объем данных по 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); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба Я бы проверял возвращаемое значение функции udp_send(). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба факта отсылки пакета нет и быть не может. Единственное что вы можете получить это то что на него выделен буфер и он добавлен в очередь отправки, а отправка произойдет во время обработки основной функции стэка. А также учитывая что UDP пакетный, а не потоковый, напихав много пакетов уходить они будут по очереди с каждым новым вызовом этой функции Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба факта отсылки пакета нет и быть не может. Неправда. Я специально проследил порядок выполнения udp_send(). Он ведёт прямиком к netif->linkoutput, то есть непосредственно к функции отправки пакета драйвером. Естественно, при условии, что arp уже сделал свои дела. Понятно, что драйвер может буферизировать пакеты перед отправкой, но не обязательно. У меня, к примеру, не буферизирует, а сразу отправляет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Real_Bastard 0 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба Я бы проверял возвращаемое значение функции udp_send(). Пробовал. Не помогает. Она на каждый вызов отвечает ОК. А пакеты выходят через один. С задержкой теряются, но 1 из 1000. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 7 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба "буферизируются или нет", это называются Блокирующие ( синхронные ) или неблокирующие ( ассинхронные ) сокеты =) обычно задается на этапе компиляции или же при создании сокета ( если правда поддерживается стеком ) так что поищите в настройках lwIP и кстати, "теряются" вы судите по приемной стороне или по WireShark ? если приемная сторона не успевает обрабатывать, то это проблема никак не относится к передающей стороне. На то он и UDP Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Real_Bastard 0 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба Ну приемное приложение у меня самописное и корявое, но 80-90Мбит\с принимает. В каждый пакет пихаю номер и инкрементирую. Без задержки почти сплошняком теряется каждый второй пакет. Поток при этом тот-же 80-90. А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба блокирующий и не блокирующий - это разве не к операционке относится? LwIP может и без нее фигачить... сейчас поглядел на UDP посылку, вызывая целую кучу функций одну за другой походу дела склеивает пакеты, добавляет заголовки, а потом правда пихает это все прямиком на выход. Как то я упустил этот момент, извиняюсь, правда обманул. Другое дело что по ходу этих функций есть кучу мест на которых процесс может прерваться и оно все вывалиться, но вываливается оно с кодами ошибок и отладочными сообщениями. Даже последняя функция выдачи наружу тоже возвращает код ошибки. Так что если send_UDP вернуло ок, то до драйвера сообщение дошло, и наверняка во все буферы (если они дальше есть) добавилось и до выхода дойдет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 7 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба > А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется. это как так: увеличили период отправки а поток не изменился ? >блокирующий и не блокирующий - это разве не к операционке относится? операционка задат лишь приоритет задач, и их переключение. А ждать завершения отправки по физическому каналу это уже другое на пальцах: *data_reg = 'a'; *data_reg = 'b'; или *data_reg = 'a'; while( data_reg_busy() ); *DATA_REG = 'b'; while( data_reg_busy() ); это же элементарно, Ватсон. Единствено что в армах это индекс управляющей структуры Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба Ну приемное приложение у меня самописное и корявое, но 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() ); это же элементарно, Ватсон. Единствено что в армах это индекс управляющей структуры Это правда элементарно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Real_Bastard 0 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба > А вот с введением задержки перед функцией отправки, потери уменьшаются до 1 из 1000. Поток не меняется. это как так: увеличили период отправки а поток не изменился ? А чего ему меняться, если у нас канал 100Мбит. А я от него больше пытаюсь выжать. вот пакеты и исчезают. А с задержкой как раз 100 и выходит. надо шарком проверить, есть ли на интерфейсе те пакеты что не дошли до приложения... Если бы каждый потерянный пакет до интерфейса доходил, то поток был бы сильно за сотню. а он и так около 90, при том что примерно половины пакетов нет. Но шарк запущу. А вдруг..... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 7 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба А чего ему меняться, если у нас канал 100Мбит. я бы назвал это пропускной способностью. А поток это уже ваши данные. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба то есть задача стоит как ограничить свои данные на выход, чтобы не засрать канал? ну если не ТСР, то надо добавить контроль потока в УДП. Подтверждать получение, фактически перейти на ТСР... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба "буферизируются или нет", это называются Блокирующие ( синхронные ) или неблокирующие ( ассинхронные ) сокеты =) Знаете, что такое "lwip raw API", pbuf_alloc() и udp_send()? Там сокетами и не пахнет. то есть задача стоит как ограничить свои данные на выход, чтобы не засрать канал? ну если не ТСР, то надо добавить контроль потока в УДП. Подтверждать получение, фактически перейти на ТСР... Не обязательно. Можно на уровне Ethernet MAC собирать информацию (пакет ушёл или не ушёл) и передавать в приложение. Это можно делать в обход lwip (скажем, через глобальные переменные). Некрасиво, но можно попробовать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Real_Bastard 0 9 декабря, 2013 Опубликовано 9 декабря, 2013 · Жалоба Запустил шарк. 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 собирать информацию ... Некрасиво, но можно попробовать. очень не хочется...но возможно это будет самый простой вариант. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться