Boost :: asio中的简单数据传输?

时间:2017-08-16 09:48:31

标签: c++ boost-asio

检查这两个简单的Server Client程序。 如在条件一中。客户端正在向服务器传输数据,Vies Versa是可能的。但是当我试图同时或连续地做。他们陷入了竞争状态。

客户计划:

#include <boost/asio.hpp>

void read(boost::asio::ip::tcp::socket& socket1, boost::system::error_code error_code)
{
    boost::asio::streambuf streambuf;
    boost::asio::read(socket1, streambuf, error_code);

    std::istream streambuf1(&streambuf);
    std::string string;
    streambuf1 >> string;
    std::cout << string << std::endl;
}

void write(boost::asio::ip::tcp::socket& socket1, boost::system::error_code error_code)
{
    std::string string("hello");
    boost::asio::write(socket1, boost::asio::buffer(string), error_code);
}

int main(int argc, char *argv[])
{
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::socket socket1(io_service);
    boost::asio::ip::tcp::resolver resolver(socket1.get_io_service());
    boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), "9999");
    boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
    boost::asio::connect(socket1, iterator);
    boost::system::error_code error_code;

    read(socket1, error_code);
    write(socket1, error_code);
    io_service.run();
    return 0;
}

这是简单服务器程序:

#include <iostream>
#include <boost/asio.hpp>

void handler(boost::system::error_code &error_code, size_t size)
{
}

void read(boost::asio::ip::tcp::socket &socket1, boost::system::error_code error_code)
{
    boost::asio::streambuf streambuf;
    boost::asio::read(socket1, streambuf, error_code);

    std::istream streambuf1(&streambuf);
    std::string string;
    streambuf1 >> string;
    std::cout << string << std::endl;
}

void write(boost::asio::ip::tcp::socket &socket1, boost::system::error_code error_code)
{
    std::string string("hello");
    boost::asio::write(socket1, boost::asio::buffer(string), error_code);
}

int main()
{
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::socket socket1(io_service);
    boost::asio::ip::tcp::acceptor acceptor(io_service,
                                            boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 9999));
    boost::system::error_code error_code;
    acceptor.accept(socket1, error_code);
    if (error_code != nullptr)
    {
        std::cerr << error_code.message() << std::endl;
    }
    write(socket1, error_code);
    read(socket1, error_code);

    io_service.run();
    return 0;
}

我的方式是错误还是我使用boost :: asio :: async_write()方法来传输来回数据。

1 个答案:

答案 0 :(得分:0)

如果您查看boost::asio::streambuf的文档,您可以在Examples部分找到可能出错的内容。

首先,您的客户连接到......什么地址? 0.0.0.0?你应该真正指定它应该连接到的位置。 这会导致错误,,因为您没有处理连接上的错误情况。也许你没有提供正确的代码来重现?

如果您不想随机崩溃,请处理所有可能的错误情况。
Boost已经帮助您解决了错误输出参数。

boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), "9999"); //0.0.0.0 ?

//---

boost::asio::ip::tcp::resolver::query query("localhost", "9999"); //Specify where to connect
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
boost::asio::connect(socket1, iterator);

现在您可以连接到远程合作伙伴,您也希望收到已发送的消息。

boost::asio::streambuf streambuf;

//Reserve some bytes for data (here adjusted for your message 'hello')
boost::asio::streambuf::mutable_buffers_type buf = streambuf.prepare(5); //Refer to documentation
auto sizeReceived = boost::asio::read(socket1, buf, error_code);
//Received bytes are 'committed'
streambuf.commit(sizeReceived);

std::istream streambuf1(&streambuf);
std::string string;
streambuf1 >> string;
std::cout << string << std::endl; //'hello'

除此之外,这是我用来测试你的样本的完整代码(不介意基类)

class Runable
{
public:
    virtual void Run() = 0;
};

class Client : public Runable
{
public:
    void Run() override
    {
        boost::asio::io_service io_service;
        boost::asio::ip::tcp::socket socket1(io_service);
        boost::asio::ip::tcp::resolver resolver(socket1.get_io_service());
        boost::asio::ip::tcp::resolver::query query("localhost", "9999"); //Specify where to connect
        boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
        boost::asio::connect(socket1, iterator);
        boost::system::error_code error_code;

        read(socket1, error_code);
        write(socket1, error_code);
        io_service.run();
    }

private:
    void read(boost::asio::ip::tcp::socket& socket1, boost::system::error_code error_code)
    {
        boost::asio::streambuf streambuf;

        boost::asio::streambuf::mutable_buffers_type buf = streambuf.prepare(5); //Refer to documentation
        auto sizeReceived = boost::asio::read(socket1, buf, error_code);
        streambuf.commit(sizeReceived);

        std::istream streambuf1(&streambuf);
        std::string string;
        streambuf1 >> string;
        std::cout << __FUNCTION__ << " # " << string << std::endl;
    }

    void write(boost::asio::ip::tcp::socket& socket1, boost::system::error_code error_code)
    {
        std::string string("hello");
        boost::asio::write(socket1, boost::asio::buffer(string), error_code);
    }
};

class Server : public Runable
{
public:
    void Run() override
    {
        boost::asio::io_service io_service;
        boost::asio::ip::tcp::socket socket1(io_service);
        boost::asio::ip::tcp::acceptor acceptor(io_service,
        boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 9999));
        boost::system::error_code error_code;
        acceptor.accept(socket1, error_code);
        if (error_code != nullptr)
        {
            std::cerr << error_code.message() << std::endl;
        }
        write(socket1, error_code);
        read(socket1, error_code);

        io_service.run();
    }

private:
    void read(boost::asio::ip::tcp::socket &socket1, boost::system::error_code error_code)
    {
        boost::asio::streambuf streambuf;

        boost::asio::streambuf::mutable_buffers_type buf = streambuf.prepare(5);
        auto sizeReceived = boost::asio::read(socket1, buf, error_code);
        streambuf.commit(sizeReceived);

        std::istream streambuf1(&streambuf);
        std::string string;
        streambuf1 >> string;
        std::cout << __FUNCTION__ << " # " << string << std::endl;
    }

    void write(boost::asio::ip::tcp::socket &socket1, boost::system::error_code error_code)
    {
        std::string string("hello");
        boost::asio::write(socket1, boost::asio::buffer(string), error_code);
    }
};

int wmain(int argv, wchar_t **args)
{
    std::thread st = std::thread([]() { Server s; s.Run(); });
    std::thread ct = std::thread([]() { std::this_thread::sleep_for(std::chrono::milliseconds(100)); Client c; c.Run(); });

    st.join();
    ct.join();

    return 0;
}

输出为:

Output

请注意,除非提供的缓冲区已满,否则boost::asio::read将不会返回。