Легкий IP: буфер не освобождается

я использую стек TCP/IP под названием lwip. Я реализовал функцию ниже для отправки пакетов данных, вдохновленную аналогичной функцией обратного вызова, которая получает пакеты данных.

каждый раз, когда пакет получен, я создаю буфер, используя

4 ответов


какую версию lwIP вы используете? В зависимости от разных версий ответы сильно различаются.

в memp_malloc() распределение функции внутри pbuf_alloc() не удалось или pbufs сцепления провалилась.Так, он возвращает значение null.

pbuf_alloc () также вернет NULL, если переданные аргументы также содержат NULL.(из-за проверки нулевых аргументов).

в более новых версиях вы можете показать, какое значение содержит макрос MEMP_OVERFLOW_CHECK? В lwIP показывает различное поведение, когда значение макроса >= 2.

и другой причиной может быть, если вы используете многопоточность, механизмы блокировки внутри pbuf_alloc () терпят неудачу, могут привести к возвращению NULL.

некоторые версии требуют вызова pbuf_init () перед вызовом pbuf_alloc ().

вы можете попробовать это:

pkt_buf = NULL;//Use NULL, just incase the NULL is not 0 as per your compiler.
pkt_buf = pbuf_alloc(PBUF_TRANSPORT, bytesToSend, PBUF_REF);
if(pkt_buf == NULL)
{
   printf("pbuf_alloc failed.\n");
}
else
{
   /* Do something with the allocated pbufs and free it. */
}

PBUF_REF не выделит буферную память для pbuf. Pbuf должен использоваться только в одном потоке, и если pbuf попадает в очередь, то pbuf_take должен быть вызван для копирования буфера.

вы также можете попробовать PBUF_RAM, который будет выделять буфер в ОЗУ.

для получения дополнительной информации вы также можете просмотреть исходные файлы используемой версии lwIP.


самым простым решением, по-видимому, является создание буфера static, т. е. повторно использовать один и тот же буфер при каждом вызове:

static struct pbuf *pkt_buf = NULL;

if( pkt_buf == NULL )
    pkt_buf = pbuf_alloc(PBUF_TRANSPORT, bytesToSend, PBUF_POOL);
if( pkt_buf == NULL )
{
    print("(TFTP) Buffer overflow!\r\n");
}

если ваш сценарий включает в себя разгрузку / перезагрузку драйвера, это приведет к утечке памяти. Чтобы исправить это, сделайте буфер статическим вне


просто мимолетная мысль, возможно, абсолютно бессмысленно. В этом коде:

if(bytesRead != 0) {
    bytesToSend = TFTP_DATA_PKT_LEN_MAX - (512 - bytesRead + 1);
} else {
    bytesToSend = TFTP_DATA_PKT_LEN_MAX - 512;
}
pkt_buf = pbuf_alloc(PBUF_TRANSPORT, bytesToSend, PBUF_POOL);

...возможно ли bytesRead принять значение 513-TFTP_DATA_PKT_LEN_MAX ?

Если бы это произошло, разве запрос на выделение нулевых байтов не завершился бы ошибкой? (это может быть проверено путем печати значения bytesToSend при переполнении буфера и проверки его ненулевого значения).


struct pbuf не представляет непрерывную область памяти. Это скорее цепочка мест памяти. Таким образом, это не будет работать в общем случае:

memcpy(pkt_buf->payload, packet, bytesToSend);

вам нужно scatter-копировать данные. Memcpy () из фрагмента кода может переполнить буфер полезной нагрузки и вызвать все виды побочных эффектов, включая неспособность освободить цепь pbuf чисто.