Написал небольшого TCP клиента для lwip (RAW), до конца он ещё не доработан, но задачу уже выполняет. Есть пара вопросов, ответы на которые я пока не нашел в справке.
void client::sendTo(ip_addr_t* ip, uint16_t port, uint8_t* pdata, uint16_t size)
{
tcp_pcb* tpcb = tcp_new();
tcp_connect(tpcb, ip, port, &callback::connection_done);
tcp_err (tpcb, &callback::connection_error);
tcp_poll (tpcb, /*&callback::polling_*/NULL, 0);
tcp_arg (tpcb, (void*)this);
memcpy(tbuf->payload, pdata, size);
tlen = size;
state = state_t::sending;
return;
}
В функции sendTo я каждый раз прошу стек выдать мне новый protocol control block для TCP. Затем в колбэке connection_done я пишу данные в стек, а в колбэке send_done закрываю pcb.
err_t client::send_done(tcp_pcb *tpcb, u16_t len)
{
close(tpcb);
return ERR_OK;
}
void client::connection_done(tcp_pcb *tpcb, err_t err)
{
tcp_sent(tpcb, &callback::send_done);
err = tcp_write(tpcb, tbuf->payload, tlen, TCP_WRITE_FLAG_COPY);
err = tcp_output(tpcb);
return;
}
void client::close(tcp_pcb* pcb)
{
tcp_arg (pcb, NULL);
tcp_sent (pcb, NULL);
tcp_recv (pcb, NULL);
tcp_err (pcb, NULL);
tcp_poll (pcb, NULL, 0);
err_t err = tcp_close(pcb);
if (err == ERR_OK)
state = state_t::closed;
return;
}
Не уверен в правильности такого подхода, мне кажется есть решение лучше. lwip_stats ничего аномального не показывает, одномоментно используется только один tcp_pcb, утечек памяти нет.