---恢復內容開始---數組
這幾天作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; //每一的鏈表的數據累加和,, } }
---恢復內容結束---