關於原子哥ENC28J60網絡通訊模塊接收數據代碼的一點疑惑

---恢復內容開始---數組

這幾天作STM32的ENC28J60網絡通訊模塊,本身在原子哥的代碼上進行修改測試,,發現一個問題,電腦和板子進行通訊的時候總隔一段時間板子就死機了.網絡

使用本身的就不會死機,,不知道緣由.....app

直接源碼tcp

struct netbuf *recvbuf;//接收buf
struct pbuf *q;    

err_t recv_err;//接收數據返回信息

u32 data_len = 0; //客戶端接收數組的長度

u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE]; //TCP客戶端接收數據緩衝區
memset(tcp_server_recvbuf,0,TCP_SERVER_RX_BUFSIZE);  //數據接收緩衝區清零

if((recv_err = netconn_recv(newconn,&recvbuf)) == ERR_OK) //接收到數據
{測試

for(q=recvbuf->p;q!=NULL;q=q->next)  //遍歷完整個pbuf鏈表
            {
                //判斷要拷貝到TCP_SERVER_RX_BUFSIZE中的數據是否大於TCP_SERVER_RX_BUFSIZE的剩餘空間,若是大於
                //的話就只拷貝TCP_SERVER_RX_BUFSIZE中剩餘長度的數據,不然的話就拷貝全部的數據
                if(q->len > (TCP_SERVER_RX_BUFSIZE-data_len)) 
                    memcpy(tcp_server_recvbuf+data_len,q->payload,(TCP_SERVER_RX_BUFSIZE-data_len));//拷貝數據
                else 
                    memcpy(tcp_server_recvbuf+data_len,q->payload,q->len);
                
                data_len = data_len + q->len;  
                
                if(data_len > TCP_SERVER_RX_BUFSIZE) break; //超出TCP客戶端接收數組,跳出    
            }

 

本身修改後的,,其實還沒優化好,,先這樣吧!不影響下面的敘述優化

struct netbuf *recvbuf;//接收buf
struct pbuf *q;    

err_t recv_err;//接收數據返回信息

u32 data_len = 0; //客戶端接收數組的長度

u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE]; //TCP客戶端接收數據緩衝區
memset(tcp_server_recvbuf,0,TCP_SERVER_RX_BUFSIZE);  //數據接收緩衝區清零

if((recv_err = netconn_recv(newconn,&recvbuf)) == ERR_OK) //接收到數據
{this

for(q=recvbuf->p;q!=NULL;q=q->next)  //遍歷完整個pbuf鏈表
            {
                if(q->tot_len > TCP_SERVER_RX_BUFSIZE)//接收的數據大於了接收數組
                {
                    printf("接收的數據大於了接收數組");
                }
                else
                {
                    memcpy(tcp_server_recvbuf+data_len,q->payload,q->len);
                    data_len = data_len + q->len; 
                }
            }

首先介紹一下存數據的這個鏈表----若是不會鏈表,,,,那就百度一下吧!或者接着看看也行,,,,,改天我寫個關於鏈表的博客,,,,,spa

struct pbuf {
  /** next pbuf in singly linked pbuf chain */
  struct pbuf *next;指向下一個鏈表

  /** pointer to the actual data in the buffer */
  void *payload;指向下一個鏈表的數據區

  /**
   * total length of this buffer and all next buffers in chain
   * belonging to the same packet.
   *
   * For non-queue packet chains this is the invariant:
   * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
   */
  u16_t tot_len;當前pbuf的數據長度與後面全部的pbuf數據之和

  /** length of this buffer */
  u16_t len;//當前pbuf數據長度
  下面的就不說了,,和咱們說的無關,,,,
  /** pbuf_type as u8_t instead of enum to save space */
  u8_t /*pbuf_type*/ type;

  /** misc flags */
  u8_t flags;

  /**
   * the reference count always equals the number of pointers
   * that refer to this pbuf. This can be pointers from an application,
   * the stack itself, or pbuf->next pointers from a chain.
   */
  u16_t ref;
};

假設數據來了,由於數據的個數不必定,而每個鏈表存數據的個數都是有限的,因此呢就出現了上圖,把數據分割依次存入幾個鏈表中code

咱們要把數據存入server

TCP_SERVER_RX_BUFSIZE  本身定義的1000
u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE]; //TCP客戶端接收數據緩衝區
這個數組

是否是應該

先看一眼這個,

struct netbuf {
  struct pbuf *p, *ptr;

 

struct netbuf *recvbuf;//接收buf
struct pbuf *q;//定義了一個q 也是用它指向下一個鏈表同next功能同樣   

err_t recv_err;//接收數據返回信息

u32 data_len = 0; //客戶端接收數組的長度

u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE]; //TCP客戶端接收數據緩衝區
memset(tcp_server_recvbuf,0,TCP_SERVER_RX_BUFSIZE);  //數據接收緩衝區清零

if((recv_err = netconn_recv(newconn,&recvbuf)) == ERR_OK) //接收到數據,,如今recvbuf->p就是第一個鏈表的地址了
{

for(q=recvbuf->p;q!=NULL;q=q->next)  //遍歷完整個pbuf鏈表       for(把第一個鏈表的地址給q, q是空的嗎, 指向下一個鏈表)
            {
其實只須要判斷第一個q->tot_len,它記錄的是本鏈表的數據長度(len記錄本鏈表的數據長度)加後面全部的數據長度,,也就是總數據長度
if(q->tot_len > TCP_SERVER_RX_BUFSIZE)//接收的數據大於了接收數組 { printf("接收的數據大於了接收數組"); } else { memcpy(tcp_server_recvbuf+data_len,q->payload,q->len);memcpy(數組的首地址+每個鏈表的數據長度累加和, 有效的數據首地址, 對應鏈表的數據長度) data_len = data_len + q->len; //每一的鏈表的數據累加和,, } }

 

---恢復內容結束---

相關文章
相關標籤/搜索