zoukankan      html  css  js  c++  java
  • 关于原子哥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; //每一的链表的数据累加和,, } }

    ---恢复内容结束---

  • 相关阅读:
    Struts2 与 Spring MVC
    RESTful Web Service
    [找程序员代写推荐]spring Scurity终于测试OK了,复杂的功能还待深入研究!发布出来一起探讨吧!
    [找程序员代写推荐]1、拖地要30分钟, 只有一个拖把 2、擦窗要30分钟, 只有一块抹布 3、切菜要30分钟, 只有一把刀 假设只有以上工具才能完成工作时,完成此三件 工作需要两个人工作多长时间?
    [原]精简高效CSS系列之二——浮动float
    [找程序员代写推荐]struts2验证+拦截器+国际化+下载excle文档+struts2二级联动+OGNL表达试+ssh集成部分代码, 项目下载、
    [原]精简高效CSS系列之一——CSS样式用法
    [原]反对网抄,没有规则可以创建目标"install" 靠谱解答
    如何鉴别程序抄袭c语言程序代写
    [原]CSS+DIV总结
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/5778872.html
Copyright © 2011-2022 走看看