网络服务器 - 发送较大的文件然后几个字节

发布于 2024-12-18 08:06:23 字数 4724 浏览 0 评论 0原文

我在发送较大的文件然后几个字节(即 700 字节)时遇到问题 由于某种原因,我可以下载一个比该文件更小的文件,但是当我尝试下载任何更大的文件时,它会在我的浏览器(Chrome)上告诉我 - 下载已停止 (即 251/700 B - 停止) 看起来它只下载了 251 个字节,然后停止了

这是我的代码: Web_Connection.h

#include <string>
#include <fstream>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class web_connection : public boost::enable_shared_from_this<web_connection>
{
public:
    typedef boost::shared_ptr<web_connection> pointer;

    static pointer create(boost::asio::io_service& io_service)
    {
        return pointer(new web_connection(io_service));
    }

    tcp::socket& socket()
    {
        return socket_;
    }

    void start()
    {
        std::filebuf *pbuf;
        std::ifstream sourcestr;
        long size;
        char * buffer;

        sourcestr.open("file-copy.exe",std::ios::in | std::ios::binary);

        // get pointer to associated buffer object
        pbuf=sourcestr.rdbuf();

        // get file size using buffer's members
        size=pbuf->pubseekoff (0,std::ios::end,std::ios::in);
        pbuf->pubseekpos (0,std::ios::in);

        // allocate memory to contain file data
        buffer=new char[size];

        // get file data  
        pbuf->sgetn (buffer,size);

        // download file http headers
        std::stringstream stream;
        stream << "HTTP/1.0 200 OK\r\n"
                    "Content-Description: File Transfer\r\n"
                    "Content-Type: application/octet-stream\r\n"
                    "Content-Transfer-Encoding: binary\r\n"
                    "Content-Disposition: attachment; filename=file.exe\r\n"
                    "Expires: 0\r\n"
                    "Cache-Control: must-revalidate, post-check=0, pre-check=0'\r\n"
                    "Pragma: public\r\n"
                    "Content-Length: " << size << "\r\n\r\n";

        message_ = stream.str();
        message_.append(buffer, size);

        /*message_ = "HTTP/1.0 200 OK\r\n"
                    "Content-Type: text/html\r\n\r\n";*/

        boost::asio::async_write(socket_, boost::asio::buffer(message_),
            boost::bind(&web_connection::handle_write, shared_from_this(),
                boost::asio::placeholders::error,
                    boost::asio::placeholders::bytes_transferred));
    }

private:
    web_connection(boost::asio::io_service& io_service): socket_(io_service)
    {}

    void handle_write(const boost::system::error_code& error,size_t bytes_transferred)
    {
    }

    tcp::socket socket_;
    std::string message_;
};

Web Server.h

#include "web_connection.h"

class web_server
{
public:
    web_server(unsigned short port)
    {
        try
        {
            acceptor_ = new tcp::acceptor(io_service, tcp::endpoint(tcp::v4(), port));
            start_accept();
            io_service.run();
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }
    }

    ~web_server()
    {
        delete acceptor_;
    }

private:
    void start_accept()
    {
        web_connection::pointer new_connection = web_connection::create(acceptor_->get_io_service());

        acceptor_->async_accept(new_connection->socket(),
            boost::bind(&web_server::handle_accept, this, new_connection,
                boost::asio::placeholders::error));
    }

    void handle_accept(web_connection::pointer new_connection, const boost::system::error_code& error)
    {
        if (!error)
        {
            new_connection->start();
            start_accept();
        }
    }
    boost::asio::io_service io_service;
    tcp::acceptor* acceptor_;
};

编辑: 我几乎通过设置这样的标题来解决这个问题:

    stream << "HTTP/1.0 200 OK\r\n"
                "Content-Description: File Transfer\r\n"
                "Content-Type: application/octet-stream\r\n"
                "Content-Transfer-Encoding: binary\r\n"
                "Content-Disposition: attachment; filename=example.exe\r\n"
                "Expires: 0\r\n"
                "Cache-Control: must-revalidate, post-check=0, pre-check=0'\r\n"
                "Pragma: public\r\n"
                "Content-Length: " << size << "\r\n\r\n";

因为我的目标是下载exe文件..

但由于某种原因访问http://127.0.0.1:8080 并不总是下载文件 有时它向我展示同样的错误 最后一个错误: asyc_write抛出的错误代码:10054类别:系统 在我的浏览器上: (Chrome:Example.exe 536/542kb - Stoppd)

但是当我刷新页面几次时它终于可以工作了:S 我怎样才能让它始终工作?

I am having problem in sending larger files then few a bytes (i.e 700bytes)
for some reason i can download a file smaller then that but when im trying to download any bigger file its telling me on my browser (Chrome) - Download Stopped
(i.e 251/700 B - Stopped)
looks like it only download 251 bytes and then stopped

this is my code:
Web_Connection.h

#include <string>
#include <fstream>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class web_connection : public boost::enable_shared_from_this<web_connection>
{
public:
    typedef boost::shared_ptr<web_connection> pointer;

    static pointer create(boost::asio::io_service& io_service)
    {
        return pointer(new web_connection(io_service));
    }

    tcp::socket& socket()
    {
        return socket_;
    }

    void start()
    {
        std::filebuf *pbuf;
        std::ifstream sourcestr;
        long size;
        char * buffer;

        sourcestr.open("file-copy.exe",std::ios::in | std::ios::binary);

        // get pointer to associated buffer object
        pbuf=sourcestr.rdbuf();

        // get file size using buffer's members
        size=pbuf->pubseekoff (0,std::ios::end,std::ios::in);
        pbuf->pubseekpos (0,std::ios::in);

        // allocate memory to contain file data
        buffer=new char[size];

        // get file data  
        pbuf->sgetn (buffer,size);

        // download file http headers
        std::stringstream stream;
        stream << "HTTP/1.0 200 OK\r\n"
                    "Content-Description: File Transfer\r\n"
                    "Content-Type: application/octet-stream\r\n"
                    "Content-Transfer-Encoding: binary\r\n"
                    "Content-Disposition: attachment; filename=file.exe\r\n"
                    "Expires: 0\r\n"
                    "Cache-Control: must-revalidate, post-check=0, pre-check=0'\r\n"
                    "Pragma: public\r\n"
                    "Content-Length: " << size << "\r\n\r\n";

        message_ = stream.str();
        message_.append(buffer, size);

        /*message_ = "HTTP/1.0 200 OK\r\n"
                    "Content-Type: text/html\r\n\r\n";*/

        boost::asio::async_write(socket_, boost::asio::buffer(message_),
            boost::bind(&web_connection::handle_write, shared_from_this(),
                boost::asio::placeholders::error,
                    boost::asio::placeholders::bytes_transferred));
    }

private:
    web_connection(boost::asio::io_service& io_service): socket_(io_service)
    {}

    void handle_write(const boost::system::error_code& error,size_t bytes_transferred)
    {
    }

    tcp::socket socket_;
    std::string message_;
};

Web Server.h

#include "web_connection.h"

class web_server
{
public:
    web_server(unsigned short port)
    {
        try
        {
            acceptor_ = new tcp::acceptor(io_service, tcp::endpoint(tcp::v4(), port));
            start_accept();
            io_service.run();
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }
    }

    ~web_server()
    {
        delete acceptor_;
    }

private:
    void start_accept()
    {
        web_connection::pointer new_connection = web_connection::create(acceptor_->get_io_service());

        acceptor_->async_accept(new_connection->socket(),
            boost::bind(&web_server::handle_accept, this, new_connection,
                boost::asio::placeholders::error));
    }

    void handle_accept(web_connection::pointer new_connection, const boost::system::error_code& error)
    {
        if (!error)
        {
            new_connection->start();
            start_accept();
        }
    }
    boost::asio::io_service io_service;
    tcp::acceptor* acceptor_;
};

EDITED:
I managed almost to solve it by setting the headers like that:

    stream << "HTTP/1.0 200 OK\r\n"
                "Content-Description: File Transfer\r\n"
                "Content-Type: application/octet-stream\r\n"
                "Content-Transfer-Encoding: binary\r\n"
                "Content-Disposition: attachment; filename=example.exe\r\n"
                "Expires: 0\r\n"
                "Cache-Control: must-revalidate, post-check=0, pre-check=0'\r\n"
                "Pragma: public\r\n"
                "Content-Length: " << size << "\r\n\r\n";

since my goal was to download exe file..

but for some reason accessing http://127.0.0.1:8080 not always downloading the file
sometimes its showing me the same error
Last Error:
Error code throwen by asyc_write: 10054 category: system
and on my browser:
(Chrome: Example.exe 536/542kb - Stoppd)

but when im refreshing the page few times it finally works :S
how can i make it always to work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文