Легкий 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 чисто.