RT-Thread-packages / at_device

AT component porting or samples for different devices
Apache License 2.0
214 stars 181 forks source link

at_device在下载大文件时出现数据错误的bug #107

Closed akinggw closed 4 years ago

akinggw commented 4 years ago

我使用AT_device通过http从网站上下载大文件时,发现每次数据都不正常,数据中总是夹杂着大量无用的数据,通过查找,发现at_socket.c这个文件中的 static size_t at_recvpkt_get(rt_slist_t rlist, char mem, size_t len) 中链表使用应该是存在问题的,修改后的代码如下: static size_t at_recvpkt_get(rt_slist_t rlist, char mem, size_t len) { rt_slist_t *node = RT_NULL; at_recv_pkt_t pkt = RT_NULL; size_t content_pos = 0, page_pos = 0;

if (rt_slist_isempty(rlist))
{
    return 0;
}

for (node = rt_slist_first(rlist); node; )
{
    pkt = rt_slist_entry(node, struct at_recv_pkt, list);

    page_pos = pkt->bfsz_totle - pkt->bfsz_index;

    //rt_kprintf("at_recvpkt_get3:%d %d\n",pkt->bfsz_totle,pkt->bfsz_index);

    if (page_pos >= len - content_pos)
    {
        memcpy((char *) mem + content_pos, pkt->buff + pkt->bfsz_index, len - content_pos);
        pkt->bfsz_index += len - content_pos;
        if (pkt->bfsz_index == pkt->bfsz_totle)
        {
            at_recvpkt_node_delete(rlist, node);
        }

        content_pos = len - content_pos;
        break;
    }
    else
    {
        memcpy((char *) mem + content_pos, pkt->buff + pkt->bfsz_index, page_pos);
        content_pos += page_pos;

        pkt->bfsz_index += page_pos;
        rt_slist_t *tmpnode = rt_slist_next(node);
        at_recvpkt_node_delete(rlist, node);
        node = tmpnode;
        //node = rt_slist_next(node);
    }
}

通过测试,现在下载数据一切正常。

akinggw commented 4 years ago

static int at_recvpkt_all_delete(rt_slist_t rlist) 这个函数同样有问题,在关闭socket时,清理接收消息列表时会报异常,导致系统中断,修改如下: static int at_recvpkt_all_delete(rt_slist_t rlist) { at_recv_pkt_t pkt = RT_NULL; rt_slist_t *node = RT_NULL;

//rt_kprintf("at_recvpkt_all_delete1.\n");

if (rt_slist_isempty(rlist))
{
    return 0;
}

rt_kprintf("at_recvpkt_all_delete2.\n");

for(node = rt_slist_first(rlist); node; )
{
    rt_slist_t *tmpnode = rt_slist_next(node);
    at_recvpkt_node_delete(rlist,node);
    node = tmpnode;
}

//rt_kprintf("at_recvpkt_all_delete3.\n");

return 0;

}

Lawlieta commented 4 years ago

https://github.com/RT-Thread/rt-thread/issues/3600 issue 讨论