Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

开发上传文件功能时出现稍大文件上传失败现象 #111

Open
ZYunfeii opened this issue Apr 10, 2022 · 6 comments
Open

开发上传文件功能时出现稍大文件上传失败现象 #111

ZYunfeii opened this issue Apr 10, 2022 · 6 comments

Comments

@ZYunfeii
Copy link

HTTP部分利用input type = file上传

<div align="center">
        <form action="d" method="post" enctype="multipart/form-data">
            <div>
                <!-- 上传文件 -->
                <p>
                    <input type="file" name="filename">
                </p>
    
            </div>
            <input type="submit" value="提交">
        </form>

</div>

当服务器recv报文时总会出现接受不完bytes_read = -1的情况,当在recv前增加一段时间sleep后能够接受稍大一点(不到1MB)文件,但更大时依旧失败。怀疑可能是bytes_read = -1时文件并未传输完成就开始解析报文了。

        // m_sleep(200); // 增加了这一句可以稍微接受大一点的文件
        int count = 0; 
        while (true)
        {
            bytes_read = recv(m_sockfd, m_read_buf + m_read_idx, READ_BUFFER_SIZE - m_read_idx, 0);
            std::cout<<bytes_read<<std::endl;
            if (bytes_read == -1)
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK){ 
                    break;
                }
                std::cout<<"errno:"<<errno<<std::endl;
                return false;
            }
            else if (bytes_read == 0)
            {
                return false;
            }
            m_read_idx += bytes_read;
        }
        return true;
@caichangzhao
Copy link

我也是这个问题 老哥你解决了吗

@ZYunfeii
Copy link
Author

我也是这个问题 老哥你解决了吗

解决了 不过换了个server项目 我个人感觉这个框架是存在小问题的

@kruicy
Copy link

kruicy commented May 12, 2022

我也是这个问题 老哥你解决了吗

解决了 不过换了个server项目 我个人感觉这个框架是存在小问题的

请问一下换了哪个server项目呀?

@wlufy
Copy link

wlufy commented Mar 2, 2023

问题好像出现在这:文件过大时,第一次解析请求体得到的结果是不完整,行状态变成LINE_OPEN,此时循环并没有结束,会执行 line_state = parse_line()。在 parse_line() 中check_idx会发生变化,导致 parse_content()函数中的判断条件永远不会成立,一直返回NO_REQUEST的状态。

// process_read()函数
while (((check_state == CHECK_STATE_CONTENT) && (line_state == LINE_OK)) || ((line_state = parse_line()) == LINE_OK))
{ 
  case CHECK_STATE_CONTENT:
        ret = parse_content(text);  
        if (ret == GET_REQUEST) {
            return do_request();
        }
        line_state = LINE_OPEN;
        break;
}

我的解决是这样的,在parse_line()函数开头加入以下判断:

if (check_state == CHECK_STATE_CONTENT) {
    if (read_idx >= content_len + check_idx) {
        return LINE_OK;
    }
    else {
        return LINE_OPEN;
    }
}

经过测试,可以实现MB级别的文件上传。
如果有理解不对的地方还请指出。

@userwang12
Copy link

我想问一下上面的老哥每个http_conn对象接收缓冲区的大小只有2048,把接收缓冲区2048大小填满了,怎么实现稍大一点的文件上传

@ZYunfeii
Copy link
Author

@userwang12 不知道现在逻辑变没变,一年多了。但当时的逻辑没有解决粘包导致大文件会上传失败,这是关键点,至于你说的缓存有关系但不是直接关系。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants