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


---恢復內容開始---

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

使用自己的就不會死機,,不知道原因.....

直接源碼

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) //接收到數據
{

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; 
                }
            }

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

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;
};

假設數據來了,因為數據的個數不一定,而每一個鏈表存數據的個數都是有限的,所以呢就出現了上圖,把數據分割依次存入幾個鏈表中

我們要把數據存入

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; //每一的鏈表的數據累加和,, } }

 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM