Skip to content

ftp在lwip2.1.2上可能存在一个问题 #3

@babboys

Description

@babboys

问题描述

stor_cmd_receive这个函数在lwip2.1.2版本上,如果socket已经断开的情况再次调用recv则会返回-1;

代码

static int stor_cmd_receive(int socket, uint8_t *buf, int bufsz, int timeout)
{
    if((socket < 0) || (buf == RT_NULL) || (bufsz <= 0) || (timeout <= 0))
        return -RT_ERROR;

    int len = 0;
    int rc = 0;
    fd_set rset;
    struct timeval tv;

    FD_ZERO(&rset);
    FD_SET(socket, &rset);
    tv.tv_sec = timeout / 1000;
    tv.tv_usec = (timeout % 1000) * 1000;

    while(bufsz > 0)
    {
        rc = select(socket + 1, &rset, RT_NULL, RT_NULL, &tv);
        if(rc <= 0)
            break;

        rc = recv(socket, buf + len, bufsz, MSG_DONTWAIT);
        if(rc <= 0)
            break;

        len += rc;
        bufsz -= rc;

        tv.tv_sec = 3;
        tv.tv_usec = 0;
        FD_ZERO(&rset);
        FD_SET(socket, &rset);
    }

    if(rc >= 0)
        rc = len;

    return rc;
}

static int stor_cmd_fn(struct ftp_session *session, char *cmd, char *cmd_param)
{
    ....
   ......
    while(1)
    {
        int recv_bytes = stor_cmd_receive(session->port_pasv_fd, (uint8_t *)reply, 4096, timeout);
        if(recv_bytes < 0)
        {
            result = -RT_ERROR;
            break;
        }
        if(recv_bytes == 0)
            break;
        if(fwrite(reply, recv_bytes, 1, fp) != 1)
        {
            result = -RT_ERROR;
            break;
        }

        timeout = 3000;
    }
    ......
    ......
}

上述代码中在接收完数据后,如果连接断开则在调用recv时已经返回了0,但是下面的代码逻辑会返回本次读取数据长度值,而不是recv返回的rc值。

    if(rc >= 0)
        rc = len;

    return rc;

当再次调用stor_cmd_receive函数接收数据时,lwip2.0.3上返回0(和linux一致),在lwip2.1.2上则会返回-1(代表出错),filezilla进行测试时就会返回失败。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions