---恢复内容开始---

这几天做STM32的ENC28J60网络通信模块,自己在原子哥的代码上进行修改测试,,发现一个问题,电脑和板子进行通信的时候总隔一段时间板子就死机了.

使用自己的就不会死机,,不知道原因.....

直接源码

struct netbuf *recvbuf;//接收buf
struct pbuf *q; err_t recv_err;//接收数据返回信息 u32 data_len = ; //客户端接收数组的长度 u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE]; //TCP客户端接收数据缓冲区
memset(tcp_server_recvbuf,,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 = ; //客户端接收数组的长度 u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE]; //TCP客户端接收数据缓冲区
memset(tcp_server_recvbuf,,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 = ; //客户端接收数组的长度 u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE]; //TCP客户端接收数据缓冲区
memset(tcp_server_recvbuf,,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; //每一的链表的数据累加和,,
}
}

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

关于原子哥ENC28J60网络通信模块接收数据代码的一点疑惑的更多相关文章

  1. cocos2dx 3.x 网络循环接收数据(RakNet::Packet* packet)单步网络接收

    void FriendFightLayer::update(float dt) { dealWithPacket(dt); if (m_isNeedSwitchToLobby) { PublicMet ...

  2. linux内核网络接收数据流程图【转】

    转自:http://blog.chinaunix.net/uid-23069658-id-3141409.html 4.3 数据接收流程图   各层主要函数以及位置功能说明:          1)s ...

  3. delphi SPCOMM 接收数据不完整!该如何解决

    SPCOMM 接收数据不完整!该如何解决   SPCOMM 接收数据不完整!我作了一个 读取地磅数据的程序,是用spcomm接收的! 总共有五台地磅,其他4台地磅数据读取都正常.但是有一台接收数据的时 ...

  4. SPCOMM 接收数据不完整!该如何解决

    SPCOMM 接收数据不完整!该如何解决   SPCOMM 接收数据不完整!我作了一个 读取地磅数据的程序,是用spcomm接收的! 总共有五台地磅,其他4台地磅数据读取都正常.但是有一台接收数据的时 ...

  5. 070 01 Android 零基础入门 01 Java基础语法 09 综合案例-数组移位 02 综合案例-数组移位-从键盘接收数据

    070 01 Android 零基础入门 01 Java基础语法 09 综合案例-数组移位 02 综合案例-数组移位-从键盘接收数据 本文知识点:综合案例-数组移位-从键盘接收数据 说明:因为时间紧张 ...

  6. python网络编程调用recv函数完整接收数据的三种方法

    最近在使用python进行网络编程开发一个通用的tcpclient测试小工具.在使用socket进行网络编程中,如何判定对端发送一条报文是否接收完成,是进行socket网络开发必须要考虑的一个问题.这 ...

  7. udp网络程序-发送、接收数据

    1. udp网络程序-发送数据 创建一个基于udp的网络程序流程很简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 代码如下: #coding=utf-8from socket im ...

  8. [Socket网络编程]由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。

    原文地址:http://blog.sina.com.cn/s/blog_70bf579801017ylu.html,记录在此方便查看 解决办法: MSDN的说明: Close 方法可关闭远程主机连接, ...

  9. Java基础知识强化之网络编程笔记06:TCP之TCP协议发送数据 和 接收数据

    1. TCP协议发送数据 和 接收数据 TCP协议接收数据:• 创建接收端的Socket对象• 监听客户端连接.返回一个对应的Socket对象• 获取输入流,读取数据显示在控制台• 释放资源 TCP协 ...

随机推荐

  1. PHP中Cookie的使用---添加/更新/删除/获取Cookie 及 自动填写该用户的用户名和密码和判断是否第一次登陆

    PHP中Cookie的使用---添加/更新/删除/获取Cookie 及 自动填写该用户的用户名和密码和判断是否第一次登陆  什么是cookie 服务器在客户端保存用户的信息,比如登录名,密码等 这些数 ...

  2. python中read()、readline()、readlines()函数

    python文件读read().readline().readlines()对比   目录 一.read方法 二.readline方法 三.readlines方法 正文 读取文件的三个方法:read( ...

  3. 【查找数字x第k为上的数字】

    #include<stdio.h> #include<math.h> // 求x用10进制表示时的数位长度 int len(int x){ ) ; )+; } // 取x的第k ...

  4. nginx禁止ip默认参数是$remote_addr无法禁止真实ip的问题

    由于网站使用了cdn所以$remote_addr获取的ip是cdn的ip,我现在先禁止某些ip访问发现无法禁止cdn传递过来的客户端的ip也就是$http_x_forwarded_for这个参数.比如 ...

  5. Java语言的特点以及Java与C/C++的异同

    Java语言的特点 1. Java为纯面向对象的语言,能够直接反应现实生活中的对象,容易理解,编程更容易. 2.跨平台,java是解释性语言,编译器会把java代码变成中间代码,然后在JVM上解释执行 ...

  6. 【疑难杂症02】ResultSet.next() 效率低下问题解决

    今天帮同事解决了一个问题,记录一下,帮助有需要的人. 一.问题解决经过 事情的经过是这样的,下午我在敲代码的时候,一个同事悄悄走到我身边,问我有没有用没用过Oracle,这下我蒙了,难道我在他们眼中这 ...

  7. Expo大作战(九)--expo的工作原理,以及版本发行说明

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,将全部来与官网 我猜去全部机翻+个人 ...

  8. 一致性Hash(Consistent Hashing)原理剖析

    引入 在业务开发中,我们常把数据持久化到数据库中.如果需要读取这些数据,除了直接从数据库中读取外,为了减轻数据库的访问压力以及提高访问速度,我们更多地引入缓存来对数据进行存取.读取数据的过程一般为: ...

  9. 调研getfit

    Gitfit实际是一个提供私人教练的服务,其主要业务有三种,“局部减脂”每天0.5-1小时,对局部高强度的刺激,快速达到塑形目地,不需要复杂器械,0基础也能跟上训练进度,并提供咨询师.营养师团队.专属 ...

  10. CentOS 7 环境下 GitLab安装部署以及账号初始化

    1. 安装相关依赖 yum install curl policycoreutils openssh-server openssh-clients -y # 确保sshd启动(正常情况下, sshd是 ...