LWIP开发遇到的问题总结归纳

开发板为STM32F429+LWIP,作为TCP\IP客户端;

电脑作为服务端进行测试;


问题1、LWIP怎么释放发送数据的缓存

LWIP TCP/IP客户端发送数据后,服务端会发送一个ACk确认包;

客户端收到ACK包后,会进入 ETH_IRQHandler中断函数中,对已发送数据包占用的缓存进行清空操作;

如果程序中没有配置 ETH_IRQHandler中断函数,则每发送一个数据包后,再tcp_write()、tcp_out()后面调用

while( ETH_CheckFrameReceived() )    {         LwIP_Pkt_Handle();    } 进行缓存区的清空;

///////

void ETH_IRQHandler(void)

{
  /* Handles all the received frames */
    /* check if any packet received */
    while(ETH_CheckFrameReceived())
    { 
      /* process received ethernet packet */
      LwIP_Pkt_Handle();
    }

/* Clear the Eth DMA Rx IT pending bits */
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
}


问题2、怎么检测到LWIP网络断开

服务端断开连接后,会给客户端发送FIN包,LWIP会进入接收回调函数中tcp_client_recv();

在接收回调函数中,判断为空的数据包,则为服务端断开连接了;调用tcp_echoclient_connection_close(tpcb, es);进行关断。

static err_t tcp_echoclient_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)

char *recdata=0;
        struct echoclient *es;
        err_t ret_err;
       LWIP_ASSERT("arg != NULL",arg != NULL);
        es = (struct echoclient *)arg;

  /* if we receive an empty tcp frame from server => close connection */
  if (p == NULL)
  {
    /* remote host closed connection */
    es->state = ES_CLOSING;
   tcp_echoclient_connection_close(tpcb, es);
    ret_err = ERR_OK;
  }   

  /* else : a non empty frame was received from echo server but for some reason err != ERR_OK */
  else if(err != ERR_OK)
  {
    /* free received pbuf*/
    pbuf_free(p);
    ret_err = err;
  }
  else if(es->state == ES_CONNECTED)
  {
  
    /* Acknowledge data reception */
    tcp_recved(tpcb, p->tot_len);  
     //add by cjh  2017-12-26            
      tcp_echoclient_cmd_handle( p->payload ,  p->len );        
     ret_err = ERR_OK;
  }
  /* data received when connection already closed */
  else
  {
    /* Acknowledge data reception */
    tcp_recved(tpcb, p->tot_len);
    
    /* free pbuf and do nothing */
    pbuf_free(p);
    ret_err = ERR_OK;
  }
  return ret_err;
}

注意:tcp_echoclient_connection_close(tpcb, es);中的处理要注意的地方;记得调用tcp_abort()函数,才能把建立的tcp链表缓存给释放掉。

//关闭与服务器的连接
void tcp_echoclient_connection_close(struct tcp_pcb *tpcb, struct tcp_client_struct * es)
{
//移除回调
    if(tpcb)
    {
       
tcp_abort(tpcb);//终止连接,删除pcb控制块
        tcp_arg(tpcb,NULL);  
        tcp_recv(tpcb,NULL);
        tcp_sent(tpcb,NULL);
        tcp_err(tpcb,NULL);
        tcp_poll(tpcb,NULL,0); 
    }        
if(es)mem_free(es); 
tcp_client_flag&=~(1<<5);//标记连接断开了
}

你可能感兴趣的:(LWIP开发遇到的问题总结归纳)