使用Boost iostream socket读写文件

4

我正在尝试使用boost iostream sockets发送和接收文件。读取文件内容并发送到流的最有效方法是什么?在服务器端如何读取此内容并写入文件?

发送:

boost::asio::io_service svc;
using boost::asio::ip::tcp;
tcp::iostream sockstream(tcp::resolver::query{ "127.0.0.1", "3780" });

std::ifstream fs;
fs.open("img.jpg", std::ios::binary);
sockstream << // send file to stream

接收:

boost::asio::io_service ios;

boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 3780);
boost::asio::ip::tcp::acceptor acceptor(ios, endpoint);

for (;;)
{
    boost::asio::ip::tcp::iostream stream;
    boost::system::error_code ec;
    acceptor.accept(*stream.rdbuf(), ec);

    if (!ec) {
        std::ofstream of;
        of.open("rcv.jpg", std::ios::binary);

        // read the file content with stream
        // write content to file
    }
}

从什么角度来看有效率呢? - Dan Mašek
1
@DanMašek 我假设(根据之前的问题)内存需求不能随着文件大小的增加而增长(即流式传输)。 - sehe
1个回答

4
我从文档示例中填补了缺失的部分:

http://www.boost.org/doc/libs/1_62_0/doc/html/boost_asio/example/cpp03/iostreams/daytime_server.cpp

这是一个简单的发送/接收程序,可以实现你所期望的功能:

在Coliru上实时运行

#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <fstream>
using boost::asio::ip::tcp;

void sender() {
    boost::asio::io_service svc;

    tcp::iostream sockstream(tcp::resolver::query { "127.0.0.1", "6768" });

    boost::iostreams::filtering_ostream out;
    out.push(boost::iostreams::zlib_compressor());
    out.push(sockstream);

    {
        std::ifstream ifs("main.cpp", std::ios::binary); // pretend this is your JPEG
        out << ifs.rdbuf();
        out.flush();
    }
}

void receiver() {

    int counter = 0;
    try
    {
        boost::asio::io_service io_service;

        tcp::endpoint endpoint(tcp::v4(), 6768);
        tcp::acceptor acceptor(io_service, endpoint);

        for (;;)
        {
            tcp::iostream stream;
            boost::system::error_code ec;
            acceptor.accept(*stream.rdbuf(), ec);

            {
                boost::iostreams::filtering_istream in;
                in.push(boost::iostreams::zlib_decompressor());
                in.push(stream);

                std::ofstream jpg("test" + std::to_string(counter++) + ".out", std::ios::binary);
                copy(in, jpg);
            }

            // break; // just for shorter demo
        }
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
        exit(255);
    }
}

int main(int argc, char**argv) {
    if (--argc && argv[1]==std::string("sender"))
       sender();
    else
       receiver();
}

当你运行接收者时:
./test

同时多次使用发送方:

./test sender

接收方将解压并将接收到的文件写入test0.out、test1.out等文件中。

你创建了一个 svc 但是没有在任何地方使用它。 - CashCow
另一个问题问我想要什么,但回答了其他事情 :( - CashCow
@CashCow 说得好(我从未意识到有一些 Asio 的东西可以在没有服务的情况下工作,所以这是我实例化的第一件事。习惯)。另外:我想现在是时候问你自己的问题了。我猜不出你想在这里读什么。 - sehe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接