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

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

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

 

Здравствуйте коллеги. Работаю с STM32F207, столкнулся с непонятной для меня ситуацией. Скорость передачи информации по протоколу tcpip в реализации lwip стека максимум до 120 килобайт в секунду (для сообщений длинной 512 байт). Пробовал менять длину пакетов, 512 байт кажется оптимальной. Принимает процессор куда быстрее, удавалось обмениваться со скоростями до 1000 килобайт в секунду. Пользовательских настроек стека не видел. В FareShark вижу что передает мои сообщения одним пакетом, и принимает тоже от PC одним пакетом. Вроде все одинаково но передача в 10 раз медленнее работает и мне это кажется очень странным. Кто-нибудь сталкивался с подобной ситуацией ?

 

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


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

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

 

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

 

у меня

10000 - 11000 байт шлются на скорости 48 мегобит

а 9000 и 12000 на 24 мбитах, а 512 падает до 0.8-0.3...

 

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

 

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

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


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

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

 

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

 

у меня

10000 - 11000 байт шлются на скорости 48 мегобит

а 9000 и 12000 на 24 мбитах, а 512 падает до 0.8-0.3...

 

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

 

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

 

 

Увеличение размера сообщения результата не дало.

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

 

 

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


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

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

 

вы подтверждаете весь пакет? tcp_recived(....)

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

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


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

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

 

вы подтверждаете весь пакет? 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
[codebox] для длинного кода, [code] - для короткого!!!

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


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

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

post-10385-1369315139_thumb.png

post-10385-1369316124_thumb.png

Изменено пользователем TSURKOV

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


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

По lwip уже много написано. Вам нужно поиграться с параметрами lwip, но вдумчиво. У меня получилась скорость ~10Мбайт в секунду на пакетах длиной 512 байт.

Прикладываю тестовый проект, в нем есть настройки lwip. Самой lwip в проекте нет.

basic_emac_lwip_1_3_1_work.rar

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

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


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

По lwip уже много написано. Вам нужно поиграться с параметрами lwip, но вдумчиво. У меня получилась скорость ~10Мбайт в секунду на пакетах длиной 512 байт.

Прикладываю тестовый проект, в нем есть настройки lwip. Самой lwip в проекте нет.

basic_emac_lwip_1_3_1_work.rar

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

 

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

 

Спасибо за помощь.

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


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

Вот нашел примеры приложений lwip, которые я изучал.

https://github.com/goertzenator/lwip/tree/m...trib-1.4.0/apps

 

В архиве, который я скинул раньше, стоит обратить внимание на "lwipopts.h".

Есть примеры в Iar'e.

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


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

Интересно, а могу я на уровне пользователя lwip стека, убедится, что переданное мной сообщение получено, и только после передавать новое. Где и какие это могут быть флаги!?

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


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

...могу я на уровне пользователя lwip стека, убедится, что переданное мной сообщение получено, и только после...

 

а разве у потока есть начало или конец???

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

 

Т.е. если говорить с точки зрения интерфейса юзвер=TCP то нет. но ели вы делаете поперёк рекомендациям самого протокола, то можно анализировать счётчик подтверждённых принятых данных. но ещё раз подчеркну - это автогеном через одно место. т.е. или TCP не нужно в этом месте, либо не так заюзано.

 

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


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

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

 

 

На самом деле хорошо было бы знать все что отправлено ушло или нет, аналог функции flush что ли, но увы, даже в С# на стороне компа эта функции в потоке ТСР - заглушка.

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


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

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

Изменено пользователем TSURKOV

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


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

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

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

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

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

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

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

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

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

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