4

I'm trying to send and receive files using boost iostream sockets. what is the most efficient way to read the contents of the file and then send to stream? And how to read this content on the server side and write to file?

Send:

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

Receive:

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
    }
}
Melissia_M
  • 323
  • 2
  • 13

1 Answers1

4

I filled in the missing pieces from the documentation example:

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

Here's a simple sender/receiver program that (I think) does what you expect:

Live On 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();
}

When you run the receiver:

./test

And use the sender several times:

./test sender

The receiver will decompress and write the file received to test0.out, test1.out etc.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • You create a svc but don't use it anywhere – CashCow Jul 17 '17 at 09:44
  • And another question that asked what I wanted to but an answer that answers something else :( – CashCow Jul 17 '17 at 13:01
  • @CashCow good point (I never realized there are Asio things that can work without a service, so it's the first thing I instantiate. Habits). Also: time to ask your own question, I guess. I cannot guess what you wanted to read here. – sehe Jul 17 '17 at 13:53