LwIP: Как избежать «Ошибки памяти (ERR_MEM)» в приложениях, которым требуется непрерывный процесс подключения-отключения?

#tcp #stm32 #ethernet #freertos #lwip

#tcp #stm32 #ethernet #freertos #lwip

Вопрос:

У меня есть встроенное клиентское приложение TCP, которое использует стек TCP / IP LwIP и raw API в локальной сети. Устройство непрерывно опрашивает серверные устройства каждые 2 секунды. Сценарий похож на приведенный ниже:

  • Клиент подключается к серверному устройству.
  • Он отправляет запрос.
  • Он получает ответ от сервера.
  • Он анализирует и обрабатывает данные.
  • Клиент закрывает соединение, чтобы подключить другое серверное устройство с другим IP.
  • Возвращается к первому шагу, и конечный автомат непрерывно запускается в этом сценарии.

Через некоторое время (300 опросов), когда я вызываю функцию tcp_connect, она возвращает ошибку памяти ERR_MEM. После этого я не могу подключать серверные устройства. Похоже, что мое приложение получает всю память после непрерывного процесса подключения-отключения, потому что это всегда происходит после определенного количества опроса.

Я проанализировал отправляющие / принимающие фреймы в Wireshark, и процесс подключения / отключения работает так, как ожидалось. В стороннем программном обеспечении TCP-сервера я проверил, работает ли процесс отключения правильно или нет.

Мне нужны некоторые рекомендации, чтобы избежать ошибки памяти в этом сценарии.

С наилучшими пожеланиями

 struct tcp_pcb *pxPCBMaster;
struct sTCPMasterClient sTCPMasterClient;

/*
* This function continously runs in super loop.
* It connects and disconnects successfully but after some time
* tcp_connect function returns ERR_MEM.
*/

void vTCPSocketTestFunc (void)
{
   pxPCBMaster = tcp_new(); 

   ip_addr_t xDestIPAddress;

   IP4_ADDR (amp;xDestIPAddress, 192, 168, 10, 7);

   // Connect to test server
   err_t eConnStatus = tcp_connect (pxPCBMaster, 
                                   amp;xDestIPAddress, 
                                   80, 
                                   prveMBTCPMPortConnectionCallback);
   if (eConnStatus != ERR_OK)
   {
       printf("DEBUG_MBTCPM_PORT: TCP Connection Error Occuredn");
       printf("DEBUG_MBTCPM_PORT: Exception Code: %dn", eConnStatus);
   }

   else
   {
      printf("DEBUG_MBTCPM_PORT: TCP Connection is successfuln");

      // Refresh Ethernet Driver and Add 2 secs Delay
      for (int i = 0; i < 200; i  )
      {
         ethernetif_input(amp;tcpNetif);
         HAL_Delay (10);
      }

      if (sTCPMasterClient != NULL)
      {
         mem_free(sTCPMasterClient );
      }

      // Close connection
      tcp_close(pxPCBMaster);

      // Aborts the connection by sending a RST (reset) segment to the remote 
      // host. The pcb is deallocated
      tcp_abort(pxPCBMaster);

      // Refresh Ethernet Driver and Add 2 secs Delay
      for (int i = 0; i < 200; i  )
      {
         ethernetif_input(amp;tcpNetif);
         HAL_Delay (10);
      }
   }
}
  

Комментарии:

1. Звучит как проблема с утечкой памяти или фрагментацией памяти.

2. Да, но я не знаю, как это происходит, потому что, когда мы вызываем функции tcp_close и tcp_abort, созданный объект tcb освобождается.

3. Вы сказали, что вы также обрабатываете данные во время каждого подключения. Если это связано с динамическим выделением памяти, это также может вызвать проблему. Причиной этого могут быть любые выделения, а не только те, которые связаны строго с TCP-соединением.

4. Я создал тестовый код, который непрерывно подключается к серверному устройству и отключается без отправки / получения и обработки каких-либо данных. Результат тот же, поэтому я уверен, что это не связано с обработкой данных.

5. Если нет конкретной причины не делать этого, вы должны установить sTCPMasterClient значение NULL после его освобождения.