【转】Lwip 断连,连接几次后不通及偶尔不通的问题.

https://blog.youkuaiyun.com/hecong_kit/article/details/24415693

新加这个函数,并在tcp_in函数里调用一下.出现不通的原因是在网络状态不流畅的情况下,连续连接N次后,LWIP默认不在连接,新建一个变量

//自己做一个函数

struct tcp_pcb *tcp_find_distant(void)

{
#if LWIP_AUTO_FREE_ACTIVE_PCB
    struct tcp_pcb *pcb  = NULL;
    struct tcp_pcb *last_pcb  = NULL;
    unsigned long last_tick = get_sys_tick();
    int pcb_num = 0;  //当前一共有几个 配置宏 MEMP_NUM_TCP_PCB


    for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next)
    {
        pcb_num++;
    }
    if(pcb_num>=MEMP_NUM_TCP_PCB)
    {
        for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next)
        {
            if(last_tick>pcb->last_tick)
            {
                last_tick = pcb->last_tick;
                last_pcb = pcb;
            }
        }
    }
    return last_pcb;
#else
    return NULL;
#endif

}

 

void
tcp_input(struct pbuf *p, struct netif *inp)
{

......

 for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
      if ((ip_addr_isany(&(lpcb->local_ip)) ||
        ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&
        lpcb->local_port == tcphdr->dest) {
        /* Move this PCB to the front of the list so that subsequent
           lookups will be faster (we exploit locality in TCP segment
           arrivals). */
        if (prev != NULL) {
          ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
                /* our successor is the remainder of the listening list */
          lpcb->next = tcp_listen_pcbs.listen_pcbs;
                /* put this listening pcb at the head of the listening list */
          tcp_listen_pcbs.listen_pcbs = lpcb;
        }
      
        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));

        //新加的代码
        //无法申请到内存块,说明当前已连接的PCB已达到上限,释放最近的active中的PCB块
        if(tcp_listen_input(lpcb)==ERR_MEM)
        {
            struct tcp_pcb *destroy_pcb = tcp_find_distant();


            if(destroy_pcb!=NULL)
            {
                tcp_abandon(destroy_pcb, 1);
                //tcp_close(destroy_pcb);
                goto LBL_RESTART;
            }
        }
        pbuf_free(p);
        return;
      }
      prev = (struct tcp_pcb *)lpcb;
    }
  }

 

LwIP BUG之TCP连接丢失

注:本文转自老衲五木的博客! LwIP所有版本包括最新的2.0版本具有以下缺陷,当用户使用raw编程并在err或poll回调函数中操作了内核全局tcp_active_pcbs链表(最典型的,比如进行了...

  • lj570681983

    尒槑: 太感谢了,成功的解决了我的问题,困扰我好久了(05-24 00:06#3楼)

  • hecong129

    辧聪: 时间太久远了,很久不做这块,应该是进到连接网络的位置(11-08 11:13#2楼)

  • dndxck

    dndxck: goto LBL_RESTART,这句的LBL_RESTART设置在哪(11-03 13:56#1楼)举报回复

<think>好的,我现在需要帮助用户解决与lwIP相关的错误问题。首先,用户提到了几个引用,其中包含不同的错误情况和解决方法。我需要先理解这些引用中的关键信息,然后整理出常见的lwIP错误及其原因和解决办法。 首先,引用[1]提到的是死循环问题,由于pcb块的申请和释放错误导致pcb->next指向自身。这可能涉及到内存管理的问题,或者是链表操作不当。解决办法需要检查pcb的申请和释放逻辑,确保链表指针正确。 引用[2]是关于内存错误的,当发送数据间隔过短时出现内存言失败。这可能是因为发送速度过快导致内存未及时释放,从而内存池耗尽。解决方法包括调整发送间隔、优化内存配置,比如增加PBUF_POOL_SIZE或MEM_SIZE,或者使用Zero-Copy技术减少内存占用。 引用[3]提到UDP发送大量数据的问题,通过修改内存区域定义解决。这里涉及到内存分区的配置,需要将LWIP的内存区分配到合适的内存段,比如.axi_ram而不是默认的.fast_ram,可能因为默认区域空间不足。 引用[4]是关于编译器兼容性的问题,使用ARM Compiler V6时需要在cc.h中添加宏定义来兼容。这说明不同编译器版本可能需要特定的配置调整。 接下来,我需要将这些信息归类,整理出常见错误类型,如内存管理错误、死循环、协议栈配置错误和编译器兼容性问题。每个错误类型需要列出原因和对应的解决方法,并参考用户提供的引用来源。 同时,根据用户提供的示例,回答需要结构清晰,分点说明,每个问题点下有原因和解决方法,并在引用处标注[^1]、[^2]等。此外,用户要求生成相关问题,我需要根据常见错误类型提出相关问题,比如如何优化内存配置,如何处理言失败等。 最后,确保回答符合系统级指令的要求,如使用正确的LaTeX格式,中文回答,引用标注正确,以及生成相关问题。需要检查是否有遗漏的引用或错误的信息,确保每个解决方法都有对应的引用支持。</think>### lwIP常见错误原因及解决方法 #### 1. **死循环问题** - **现象**:系统卡死在TCP连接处理循环中,例如`tcp_active_pcbs`链表出现自引用。 - **原因**:`pcb`块申请/释放逻辑错误,导致链表指针异常(如`pcb->next`指向自身)。 - **解决方法**: - 检查`pcb`的创建与销毁逻辑,确保链表操作正确。 - 添加链表遍历时的循环保护机制,例如设置最大遍历次数。 #### 2. **内存错误(言失败)** - **现象**:发送数据过快时触发言错误(如`mem_free: illegal memory`或`pbuf_free: p->ref > 0`)[^2]。 - **原因**: - 内存池耗尽(如`PBUF_POOL`或`MEM_SIZE`配置不足)。 - 发送速率超过协议栈处理能力,导致未释放内存被重复申请。 - **解决方法**: - 增加内存池大小:修改`lwipopts.h`中的`PBUF_POOL_SIZE`和`MEM_SIZE`。 - 降低发送频率或使用Zero-Copy API(如`netconn_send`)减少内存占用。 - 检查应用层逻辑,确保及时释放`pbuf`(调用`pbuf_free()`前验证`p->ref > 0`)。 #### 3. **内存区域配置错误** - **现象**:UDP发送大量数据时崩溃或数据丢失[^3]。 - **原因**:内存分配区域(如`.fast_ram`)空间不足。 - **解决方法**: - 修改`cc.h`中的`LWIP_MEM_SECTION`宏,将内存分配到更大容量的区域(如`.axi_ram`)。 - 确认链接脚本中目标内存区域的大小与LWIP配置匹配。 #### 4. **编译器兼容性问题** - **现象**:使用ARM Compiler V6编译时出现语法错误[^4]。 - **原因**:旧版宏定义不兼容新编译器。 - **解决方法**: - 在`cc.h`中添加编译器版本判宏: ```c #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #define __CC_ARM //启用V6编译器兼容模式 #endif ``` #### 5. **TCP/IP协议栈初始化错误** - **现象**:络功能无法启动或频繁连。 - **原因**: - 物理层驱动未正确配置(如PHY芯片初始化失败)。 - 协议栈参数(如`MEMP_NUM_TCP_PCB`)设置过小。 - **解决方法**: - 检查PHY芯片的复位、时钟和中配置。 - 增大`lwipopts.h`中的连接数限制参数(如`MEMP_NUM_TCP_PCB`)。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值