消息队列为什么会出现获取到的内容有旧的数据?

发布于 2020-11-27 09:54:14

我有一个【接收线程】阻塞去【消息队列】中取数据,有数据就发送,没有就等待
我有一个【发送线程】不定时向【消息队列】中发数据,发送的内容不固定长度但不超过128byte
现象是我接收线程取读取是会出现含有旧数据
例如:
第一次发送"1234567890",10个,接收显示"1234567890",10个
第二次发送"abcde",5个,接收显示"abcde67890",10个
这就不对了,我以为是我发给【消息队列】发送buf或者接收接收buf没有清空,
加了清空后依然存在。
除此之外还有什么原因可能导致出现这样的问题?

补充:
【发送线程】是我概念上的,因为所有发往服务器的数据都通过
【rt_mq_send(&tcp_client_mq, data, size);】发给tcp_client_send线程,统一发往服务器,而且有【串口线程】和【tcp客户端接收函数】调用【数据处理函数】后就
发消息到队列中,【定时器】触发后也会发送到队列中,发送位置1、2就在数据处理函数中的

发送位置1:
case Report_Date:{//串口 要求 模块 上报属性
    cJSON *root = cJSON_CreateObject();
    cJSON *propert = cJSON_CreateObject();
    cJSON_AddItemToObject(root, "propert", propert);
    cJSON_AddNumberToObject(root, "Order", 1);
    cJSON_AddStringToObject(root, "DeviceNo", "614ca5bc");
    cJSON_AddStringToObject(root, "Name", "Wine cabinet");
    cJSON_AddNumberToObject(root, "SerialNumber", 3);
    if(buf[index+4] == 1)
        cJSON_AddStringToObject(propert, "Switch", "On");
    else if(buf[index+4] == 2)
        cJSON_AddStringToObject(propert, "Switch", "Off");
    cJSON_AddNumberToObject(propert, "LightLevel", buf[index + 5]);
    cJSON_AddNumberToObject(propert, "Battery", buf[index + 6]);
    char* data_cjson = cJSON_Print(root);
    rt_kprintf("Send cJson data:[%s],%d",data_cjson,strlen(data_cjson));
    
    rt_mq_send(&tcp_client_mq, data_cjson, strlen(data_cjson));
    
    data_cjson = RT_NULL;
    cJSON_free(root);
    cJSON_free(propert);
}break;

发送位置2:
static void timeout_entry(void *parameter)
{//15s定时器
    sn++;
    if(sn>=0xffff)
        sn=0;
    cJSON_SetIntValue(item, sn);
    cJSON_SetNumberValue(item, sn);
    char* temp = cJSON_Print(heartbeat_root);
    rt_kprintf("[timeout_entry] data [%s],%d\n",temp,strlen(temp));
    
    rt_mq_send(&tcp_client_mq,temp,strlen(temp));
    
    rt_free(temp);
}

发送位置3:
case 99:{    
    char *d = cJSON_Print(root);
    rt_mq_send(&tcp_client_mq, d, strlen(d));
    }break;

接收线程:
void tcp_client_send_entry(void* parameter)
{
    char msg_buf[NET_DATA_SIZE_MAX]={0};
    int send_result;
    while(1)
    {
        //memset(msg_buf, 0, sizeof(msg_buf));
        rt_mq_recv(&tcp_client_mq, &msg_buf[0], sizeof(msg_buf), RT_WAITING_FOREVER);//等待要发往服务器的数据
        rt_kprintf("[tcp_client_send_entry] got mes [%s],%d,Socket:%d\n",msg_buf,strlen(msg_buf),server_socket);
        send_result = send(server_socket, msg_buf, strlen(msg_buf), 0);
        if(send_result <= 0)
        {
            if(send_result = 0)
                rt_kprintf("[tcp_client_send] Send warning, return 0\n");
             if(send_result < 0)
                rt_kprintf("[tcp_client_send] socket error\n");
//            closesocket(server_socket);
//            server_socket = -1;
//            rt_thread_delete(tcp_client_send_t);
//            tcp_client_send_t = RT_NULL;
//            return;
        }
        else//if(send_result > 0)
        {
            rt_kprintf("[tcp_client_send] send_result:%d\n",send_result);
        }
        for(rt_uint16_t i = 0; i < NET_DATA_SIZE_MAX; i++) msg_buf[i] = 0;
    }
}
//队列
#define NET_DATA_SIZE_MAX 128
static rt_uint8_t tcp_client_mq_pool[NET_DATA_SIZE_MAX*4];//最多存4
if (RT_EOK != rt_mq_init(&tcp_client_mq,
                        "tcp_client_mq",
                        &tcp_client_mq_pool[0],
                        NET_DATA_SIZE_MAX,
                        sizeof(tcp_client_mq_pool),
                        RT_IPC_FLAG_FIFO))
{ 
    rt_kprintf("init tcp_client_mq failed.\n"); 
}

查看更多

关注者
0
被浏览
590
小半仙
小半仙 2020-11-28

消息队列的接收函数,接收数据后没有清内存,要修改IPC的消息队列接收函数,这是一个bug

3 个回答
yangjie
yangjie 2020-11-27

应该是用法问题吧,发送和接收代码也贴出来看看呢

JQRR_7669
JQRR_7669 认证专家 2020-11-28

rt_mq_recv前面的memset被注释掉的缘故,接收长度不是真实返回长度,是使用strlen计算所得

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览