【问题标题】:c++, boost: how to fill buffer and transfer (image) file data over network?c++,boost:如何填充缓冲区并通过网络传输(图像)文件数据?
【发布时间】:2010-08-05 15:10:52
【问题描述】:

我正在开发一个需要通过网络发送“文件名”、“文件大小”和文件数据的应用程序。我使用 boost 创建了一个服务器,现在它读取文件大小和名称。

我想知道如何用文件数据填充缓冲区(如果需要)以及如何将其传输到服务器。

这就是我现在得到的:

#ifndef OFXFILETRANSFERSENDH
#define OFXFILETRANSFERSENDH

#undef check // necessary to get Boost running on Mac

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

#include "ofxFileTransferConnection.h"
using boost::asio::ip::tcp;
class ofxFileTransferSend : public boost::enable_shared_from_this<connection> {
public:
    typedef boost::shared_ptr<ofxFileTransferSend> pointer;
    static pointer create(
                        boost::asio::io_service& rIOService
                        ,std::string sServer
                        ,const char* sPort) 
    {
        return pointer(new ofxFileTransferSend(rIOService,sServer, sPort));
    }


private:
    //--------------------------------------------------------------
    ofxFileTransferSend(
                    boost::asio::io_service &rIOService
                    ,const std::string sServer
                    ,const char* sPort
    )
        :port(sPort)
        ,socket_(rIOService)
        ,resolver_(rIOService)
    {

        tcp::resolver::query query(sServer, sPort);
        resolver_.async_resolve(
                            query
                            ,boost::bind(
                                    &ofxFileTransferSend::handleResolve
                                    ,this
                                    ,boost::asio::placeholders::error
                                    ,boost::asio::placeholders::iterator
                            )
        );
    }


    //--------------------------------------------------------------
    void handleResolve(
        const boost::system::error_code &rError
        ,tcp::resolver::iterator oEndPointIterator
    )
    {
        if (!rError) {
            tcp::endpoint end_point = *oEndPointIterator;
            socket_.async_connect(
                                end_point
                                ,boost::bind(
                                    &ofxFileTransferSend::handleConnect
                                    ,this
                                    ,boost::asio::placeholders::error
                                    ,++oEndPointIterator
                                )
            );
        }
        else {
            std::cout << "Error while resolving server: " << std::endl;
        }
    }

    //--------------------------------------------------------------
    void handleConnect(
        const boost::system::error_code &rError
        ,tcp::resolver::iterator rOEndPointIterator
    )
    {
        if(!rError) {
            std::cout << "Connected to remote server!" << std::endl;
            std::size_t size = 1235;
            std::ostream send_data_stream(&send_data);
            send_data_stream << "filename.jpg" << "\r\n";
            send_data_stream << size << "\r\n";

            boost::asio::async_write(
                            socket_
                            ,send_data
                            ,boost::bind(
                                &ofxFileTransferSend::handleSendFileInfo
                                ,this
                                ,boost::asio::placeholders::error
                            )
            );
        }
        else {
            // @todo on failure retry!
            std::cout << "Error connecting to ofxFileTransferServer:" << rError.message()<< std::endl;
        }
    }


    //--------------------------------------------------------------
    void handleSendFileInfo(
        const boost::system::error_code &rError
    )
    {
        if(!rError) {
            cout << "okay nice, send file data done!\n";
        }
        else {
            std::cout << "Error sending file info: " << rError.message() << std::endl;
        }
    }   

    tcp::resolver resolver_;
    tcp::socket socket_;
    boost::asio::streambuf send_data;
    const char* port;
};
#endif

【问题讨论】:

    标签: c++ file networking boost transfer


    【解决方案1】:

    将文件转储到网络上怎么样?这就是 HTTP 的工作方式。事实上,我看到您使用的协议几乎与 HTTP 相同。首先以明文形式发送所有元数据(名称、大小等),在一个空行中作为元数据的终止符(\r\n),现在您只需要转储文件本身:

    void handleSendFileInfo(
        const boost::system::error_code &rError
    )
    {
        if(!rError) {
            std::ofstream fileData(fileName);
    
            boost::asio::async_write(
                            socket_
                            ,fileData
                            ,boost::bind(
                                &ofxFileTransferSend::handleSendFileData
                                ,this
                                ,boost::asio::placeholders::error
                            )
            );
        }
        else {
            std::cout << "Error sending file info: " << rError.message() << std::endl;
        }
    }   
    

    【讨论】:

    • 您好詹尼,非常感谢您的回复!这会正确发送所有数据吗?还是所有数据都以块的形式发送,我需要用块多次调用这个 async_write() 吗?
    • 这应该是所有数据。真的不需要其他任何东西。
    • 嗨,Gianni,我明天要试试……我的代码正在运行。不过非常感谢!没想到这么简单!
    • @pollux 很高兴能提供帮助。但是,我认为您应该在接受答案之前尝试一下。你永远无法确定会发生什么。 ;-)
    • 真的有用吗?我原以为 std::ifstream 在概念上会起作用!那也没用:(
    猜你喜欢
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多