天天看點

解決stm32+lwip接收伺服器大資料包

基于lwip協定,實作從伺服器上拉取資料進行接收儲存,由于資料量比較大,是以不能一次接收,隻能分開接收,每次接收1460位元組資料,接收完成進行合并,主要處理分為兩點:

  1. 修改lwip配置代碼lwipopts.h檔案中#define PBUF_POOL_BUFSIZE宏定義修改大一點,比如1024;
  2. 由于動态配置設定堆棧空間有限,是以直接定義char recev_buf[1500]和static char recdata[10000]用于接收,每次接收資料暫存在recev_buf,接收完成後追加到recdata中進行儲存;

附上部分代碼:

/**
  * 函數功能: TCP接收資料回調函數
  * 輸入參數: 無
  * 返 回 值: 無
  * 說    明: 無
  */
static err_t tcp_echoclient_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{ 
  
  struct echoclient *es;
  err_t ret_err;
  struct pbuf *q;

  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;
    if(es->p_tx == NULL)
    {
       /* we're done sending, close connection */
       tcp_echoclient_connection_close(tpcb, es);
    }
    else
    {    
      /* send remaining data*/
      tcp_echoclient_send(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*/
    if (p != NULL)
    {
      pbuf_free(p);
    }
    ret_err = err;
  }
  else if(es->state == ES_CONNECTED)
  {
    /* increment message count */
    message_count++;
    
    /* Acknowledge data reception */
    tcp_recved(tpcb, p->tot_len);  
    
    l = p->payload;
    l = l + p->len;
    *l = '\0';
    printf("%s",p->payload);
    strcpy(recev_buf,p->payload);
         
    q = p;
            
    while(q->next != NULL)
    {
        q = q->next;
        tcp_recved(tpcb, q->tot_len); 
               
        l = q->payload;
        l = l + q->len;
        *l = '\0';
        printf("%s",q->payload);
        strcat(recev_buf,q->payload);   
     }
	  
    pbuf_free(p);

    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;
  }
  if(flag)
  {
    strcat(recdata,recev_buf);
  }
  else
  {
    strcpy(recdata,recev_buf);
  }
  
  //還有資料待接收
  if(strlen(recev_buf) == 1460)
  {
    flag = 1;
  }
  else//接收完成
  {
    flag = 0;
    
    }
  
  return ret_err;
}
           

繼續閱讀