OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6466|回复: 2

freertos+lwip tcp接收数据超时问题

[复制链接]

1

主题

3

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2018-8-29
在线时间
3 小时
发表于 2018-8-29 12:38:23 | 显示全部楼层 |阅读模式
1金钱
int8_t send_http_request(char* sendBuf,void (*handle_function)(cJSON* valid_data))
{
        IP4_ADDR(&server_ipaddr,MAIN_SERVER_IP_ADDR0,MAIN_SERVER_IP_ADDR1,MAIN_SERVER_IP_ADDR2,MAIN_SERVER_IP_ADDR3);
        server_port = MAIN_SERVER_PORT;
               
        tcp_clientconn = netconn_new(NETCONN_TCP);
        if(tcp_clientconn==NULL)
        {
                printf("新建连接失败\r\n");
                return;
        }
       
        errCode = netconn_connect(tcp_clientconn,&server_ipaddr,server_port);
        if(errCode == ERR_OK)
        {       
                finalRecvBuf = (char*)mymalloc(4000*sizeof(char));//定义finalRecvBuf长度是数据包的总长度
                memset(finalRecvBuf,0x00,4000);
               
                tcp_clientconn->send_timeout = 3000;//发送超时时间设定3秒
               
                //NETCONN_COPY,会将数据拷贝给内核进程,这种方式,用户可以直接复用buf
                errCode = netconn_write(tcp_clientconn,sendBuf,strlen((const char*) sendBuf),NETCONN_NOCOPY);
//                if(errCode == ERR_OK)
//                {
//                        DEBUG_PRINT_VAR("send sucess\r\n");
//                }
//                else
//                {
//                        DEBUG_PRINT_VAR("send failure\r\n");
//                }
               
                tcp_clientconn->recv_timeout  = 5000;//接收超时时间设定5秒
               
//                netconn_recv(tcp_clientconn,&recevingBuf);

                //循环接收数据
                while(1)
                {
                        errCode = netconn_recv(tcp_clientconn,&recevingBuf);
                        printf("errCode--->%d\r\n",errCode);
                               
                        if(errCode == ERR_OK && recevingBuf!=NULL)
                        {
                                taskENTER_CRITICAL();         //进入临界区                       
                                for(;;)
                                {
                                        //若第一个数据包的长度和总长度大小相等,直接拷贝出来
                                        if(recevingBuf->p->tot_len == recevingBuf->p->len)
                                        {
//                                                DEBUG_PRINT_VAR("尾包数据包------->%s\r\n",(char *)recevingBuf->p->payload);
                                               
                                                strncat(finalRecvBuf,(char *)recevingBuf->p->payload,recevingBuf->p->tot_len);
                                               
                                                break;
                                        }
                                        //若第一个数据包的长度和总长度大小不相等,需要循环将每个包里的内容拼接到buf中
                                        else
                                        {
//                                                DEBUG_PRINT_VAR("单个数据包------->%s\r\n",(char *)recevingBuf->p->payload);
                                               
                                                strncat(finalRecvBuf,(char *)recevingBuf->p->payload,recevingBuf->p->len);
                                               
        //                                        DEBUG_PRINT_VAR("p->payload 累加buf---->%s\r\n",finalRecvBuf);
        //                                        DEBUG_PRINT_VAR("数据包长度--->%d\r\n",strlen(finalRecvBuf));                                               
                                                recevingBuf->p = recevingBuf->p->next;
                                        }
                                }
                                printf("接收正常\r\n");
//                                printf("p->payload total内容是 ---->%s,接收数据长度--->%d\r\n",finalRecvBuf,strlen(finalRecvBuf));                                                                                                               
                                netbuf_delete(recevingBuf);//需要在此时释放recevingBuf否则会导致内存异常
                                recevingBuf = NULL;
                                taskEXIT_CRITICAL();
                        }
                        else if(errCode == ERR_MEM)
                        {
                                break;
                        }
                        else if(errCode == ERR_CLSD)//服务器关闭连接
                        {       
                                errCode = 0;
                                netconn_close(tcp_clientconn);
                                netconn_delete(tcp_clientconn);                               
                                break;
                        }
                        else if(errCode == ERR_TIMEOUT)//超时也break出去
                        {
                                printf("接收超时\r\n");
                                errCode = -1;
                                continue;
                        }                               
                }
}

这个函数接收1000字节以上的数据,能够成功3、4次,之后便一直是超时,很郁闷,求指点迷津




最佳答案

查看完整内容[请看2#楼]

记录一下,目前已经解决了这个问题。是lwip内存分配策略导致的问题,将pbuf_pool_bufsize 改为了LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN),并将分配策略改为MEMP_MEM_MALLOC
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2018-8-29
在线时间
3 小时
 楼主| 发表于 2018-8-29 12:38:24 | 显示全部楼层
记录一下,目前已经解决了这个问题。是lwip内存分配策略导致的问题,将pbuf_pool_bufsize 改为了LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN),并将分配策略改为MEMP_MEM_MALLOC
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2018-8-29
在线时间
3 小时
 楼主| 发表于 2018-8-29 12:42:47 | 显示全部楼层
而且是不可恢复的超时,即便新建连接、发送、接收,还是超时,逆天了。ps:接收少量内容<200字节没用这个现象
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 20:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表