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

 
 
 
Reply to this topicStart new topic
> Низкая скорость передачи данных по TCP как быть?
TSURKOV
сообщение May 21 2013, 14:46
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 1-11-05
Пользователь №: 10 385



Низкая скорость передачи данных по TCP как быть?

Здравствуйте коллеги. Работаю с STM32F207, столкнулся с непонятной для меня ситуацией. Скорость передачи информации по протоколу tcpip в реализации lwip стека максимум до 120 килобайт в секунду (для сообщений длинной 512 байт). Пробовал менять длину пакетов, 512 байт кажется оптимальной. Принимает процессор куда быстрее, удавалось обмениваться со скоростями до 1000 килобайт в секунду. Пользовательских настроек стека не видел. В FareShark вижу что передает мои сообщения одним пакетом, и принимает тоже от PC одним пакетом. Вроде все одинаково но передача в 10 раз медленнее работает и мне это кажется очень странным. Кто-нибудь сталкивался с подобной ситуацией ?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 21 2013, 21:45
Сообщение #2


Гуру
******

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



попробуйте послать пакет длинной 10000 и 11000 байт. Может поехать значительно шустрее...

в настройке ЛВИП по умолчанию от размера пакета есть смешные провалы в производительности, я так понимаю какая то кратность с размером окна. Но маленькие пакеты шлются очень медленно, чуть больше быстрее, потом опять замедление, пакеты с длинной больше единичной посылки в некоторых местах имеют пики скорости.

у меня
10000 - 11000 байт шлются на скорости 48 мегобит
а 9000 и 12000 на 24 мбитах, а 512 падает до 0.8-0.3...

ну это если не крутить настройки... и у меня не стм, но это не важно, это ЛвИП

найдите размер окна, и отложенный акноледж данных
Go to the top of the page
 
+Quote Post
TSURKOV
сообщение May 22 2013, 14:42
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 1-11-05
Пользователь №: 10 385



Цитата(Golikov A. @ May 22 2013, 00:45) *
попробуйте послать пакет длинной 10000 и 11000 байт. Может поехать значительно шустрее...

в настройке ЛВИП по умолчанию от размера пакета есть смешные провалы в производительности, я так понимаю какая то кратность с размером окна. Но маленькие пакеты шлются очень медленно, чуть больше быстрее, потом опять замедление, пакеты с длинной больше единичной посылки в некоторых местах имеют пики скорости.

у меня
10000 - 11000 байт шлются на скорости 48 мегобит
а 9000 и 12000 на 24 мбитах, а 512 падает до 0.8-0.3...

ну это если не крутить настройки... и у меня не стм, но это не важно, это ЛвИП

найдите размер окна, и отложенный акноледж данных



Увеличение размера сообщения результата не дало.
Посмотрел повнимательнее в wireshark и увидел что там есть странные сегменты красным на черном фоне надпись tcp previous segment not captured. Если снижаю размер буффера до 264 байт, то подобных сообщений нет. Может как то с этим связанно ?

Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 22 2013, 16:19
Сообщение #4


Гуру
******

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



у вас очень маленькое окно, получается частые перепосылы и остановки.

вы подтверждаете весь пакет? tcp_recived(....)
там буфер р имеет кроме p->len еще и p->total_len, и ссылки на след пакеты, может пока туда-суда окно и забилось?
Go to the top of the page
 
+Quote Post
TSURKOV
сообщение May 23 2013, 09:20
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 1-11-05
Пользователь №: 10 385



Цитата(Golikov A. @ May 22 2013, 19:19) *
у вас очень маленькое окно, получается частые перепосылы и остановки.

вы подтверждаете весь пакет? tcp_recived(....)
там буфер р имеет кроме p->len еще и p->total_len, и ссылки на след пакеты, может пока туда-суда окно и забилось?


Насколько я понимаю подтверждение tcp_recived это для случая когда процессор принимает. Во всяком случае я так делал.
Код
err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
   // обработка принятого пакета
    
     tcp_recved(tpcb,p->tot_len);
     pbuf_free(p);

}

Для случая передачи я просто вызываю calback функцию tcp_sent(ptcp_pcb, tcp_client_sent)
Хотя ее смысл мне не понятен (функцию взял из примера) в if программа не заходит.
Код
err_t tcp_client_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
  struct tcp_client_struct *es;

  LWIP_UNUSED_ARG(len);

  es = (struct tcp_client_struct *)arg;
  
  if(es->p_tx != NULL)
  {
    tcp_client_send(tpcb, es);
  }

  return ERR_OK;
}

вообще мой обработчик передачи крутится в основном цикле и выглядит примерно так
Код
void SendDataHandler(void)
{

   // запаковка данных
      
      if(tcp_sndbuf(ptcp_pcb) >= msg_len)
      {
        err = tcp_write(ptcp_pcb,&tx_tcp_msg,msg_len,1);
        tcp_sent(ptcp_pcb, tcp_client_sent);  
      }
}

если err == ERR_OK значит данные переданы.

Сообщение отредактировал IgorKossak - May 23 2013, 12:51
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
TSURKOV
сообщение May 23 2013, 13:19
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 1-11-05
Пользователь №: 10 385



скриншот wareshark. Такое впечатление, что процессор не получает некоторые подтверждения от PC и повторно шлет пакеты. Что и снижает общую скорость.

Сообщение отредактировал TSURKOV - May 23 2013, 13:36
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
taoga
сообщение May 23 2013, 18:13
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-10-09
Пользователь №: 52 809



По lwip уже много написано. Вам нужно поиграться с параметрами lwip, но вдумчиво. У меня получилась скорость ~10Мбайт в секунду на пакетах длиной 512 байт.
Прикладываю тестовый проект, в нем есть настройки lwip. Самой lwip в проекте нет.
Прикрепленный файл  basic_emac_lwip_1_3_1_work.rar ( 3.08 мегабайт ) Кол-во скачиваний: 166

Может чем поможет.
Go to the top of the page
 
+Quote Post
TSURKOV
сообщение May 24 2013, 12:29
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 1-11-05
Пользователь №: 10 385



Цитата(taoga @ May 23 2013, 21:13) *
По lwip уже много написано. Вам нужно поиграться с параметрами lwip, но вдумчиво. У меня получилась скорость ~10Мбайт в секунду на пакетах длиной 512 байт.
Прикладываю тестовый проект, в нем есть настройки lwip. Самой lwip в проекте нет.
Прикрепленный файл  basic_emac_lwip_1_3_1_work.rar ( 3.08 мегабайт ) Кол-во скачиваний: 166

Может чем поможет.


Помогло. Но правда в другом. После вызова tcp_write стал делать вызов tcp_output (подсмотрел в Вашем коде). Скорость возросла более чем в два раза, местами до полу мегабайта дотягивает. Но этого все равно маловато, видимо это не основная причина, попрежнему много коллизий и перезапросов как с одной так и с другой стороны. Когда тестирую две программы на PC все передается чисто, равномерно, с процессором из за перезапросов все дергается. Периодически отправляет несколько раз один и тот же пакет данных. Буду думать дальше.

Спасибо за помощь.
Go to the top of the page
 
+Quote Post
taoga
сообщение May 24 2013, 18:05
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-10-09
Пользователь №: 52 809



Вот нашел примеры приложений lwip, которые я изучал.
https://github.com/goertzenator/lwip/tree/m...trib-1.4.0/apps

В архиве, который я скинул раньше, стоит обратить внимание на "lwipopts.h".
Есть примеры в Iar'e.
Go to the top of the page
 
+Quote Post
TSURKOV
сообщение May 30 2013, 08:56
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 1-11-05
Пользователь №: 10 385



Интересно, а могу я на уровне пользователя lwip стека, убедится, что переданное мной сообщение получено, и только после передавать новое. Где и какие это могут быть флаги!?
Go to the top of the page
 
+Quote Post
kolobok0
сообщение May 30 2013, 19:52
Сообщение #11


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(TSURKOV @ May 30 2013, 12:56) *
...могу я на уровне пользователя lwip стека, убедится, что переданное мной сообщение получено, и только после...


а разве у потока есть начало или конец???
имхо, на лицо типичная ошибка - не понимания принципов TCP.

Т.е. если говорить с точки зрения интерфейса юзвер=TCP то нет. но ели вы делаете поперёк рекомендациям самого протокола, то можно анализировать счётчик подтверждённых принятых данных. но ещё раз подчеркну - это автогеном через одно место. т.е. или TCP не нужно в этом месте, либо не так заюзано.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 31 2013, 05:33
Сообщение #12


Гуру
******

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



Другими словами вам на поток предлагают навернуть еще протокол...


На самом деле хорошо было бы знать все что отправлено ушло или нет, аналог функции flush что ли, но увы, даже в С# на стороне компа эта функции в потоке ТСР - заглушка.
Go to the top of the page
 
+Quote Post
TSURKOV
сообщение Jun 3 2013, 12:39
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 1-11-05
Пользователь №: 10 385



Еще раз большое спасибо. wink.gif Все отлично заработало, проблема оказалась в программе на ПК.

Сообщение отредактировал TSURKOV - Jun 3 2013, 12:41
Go to the top of the page
 
+Quote Post

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

 


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


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