c++ - 使用 boost 异步发送和接收自定义数据包?

标签 c++ asynchronous boost tcp asio

我正在尝试使用 boost 异步发送和接收自定义数据包,根据我当前的实现,我有一些问题:

tcpclient.cpp

#include "tcpclient.h"
#include <boost/chrono.hpp>
#include "../utils/logger.h"

tcpclient::tcpclient(std::string host, int port) :
        _endpoint(boost::asio::ip::address::from_string(host), port), _socket(_ioservice) {

    logger::log_info("Initiating client ...");
}

void tcpclient::start() {
    connect();
    _ioservice.run();
}

void tcpclient::connect() {
    _socket.async_connect(_endpoint, std::bind(&tcpclient::connect_handler, this, std::placeholders::_1));
}

void tcpclient::receive() {
    boost::asio::async_read(_socket, boost::asio::buffer(data, HEADER_LEN), std::bind(&tcpclient::read_handler, this, std::placeholders::_1));
}

void tcpclient::connect_handler(const boost::system::error_code &error) {
    if (!error) {
        _status = CONNECTED;
        logger::log_info("Connected to " + get_remote_address_string());
        receive();
    } else {
        _status = NOT_CONNECTED;
        _socket.close();
        _timer.expires_from_now(boost::asio::chrono::seconds{2});
        _timer.async_wait(std::bind(&tcpclient::reconnect_handler, this, std::placeholders::_1));
        logger::log_info("Failed to connect");
    }
}

void tcpclient::reconnect_handler(const boost::system::error_code &error) {
    connect();
}

void tcpclient::read_handler(const boost::system::error_code& error, std::size_t bytes_transferred)
{
    logger::log_info("reading some data?");
}


std::string tcpclient::get_remote_address_string() {
    return _socket.remote_endpoint().address().to_string() + ":" + std::to_string(_socket.remote_endpoint().port());
}

tcpclient.h

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


enum ConnectionStatus{
    NOT_CONNECTED,
    CONNECTED
};


class tcpclient {

public:

    tcpclient(std::string host, int port);

    void start();

    void connect();

private:

    ConnectionStatus _status = NOT_CONNECTED;

    const int HEADER_LEN = 0x01;

    void receive();

    void connect_handler(const boost::system::error_code& error);

    void reconnect_handler(const boost::system::error_code &error);

    void read_handler(const boost::system::error_code& error);

    std::string get_remote_address_string();


    boost::asio::io_service _ioservice;
    boost::asio::ip::tcp::endpoint _endpoint;
    boost::asio::ip::tcp::socket _socket;
    boost::asio::steady_timer _timer{_ioservice, boost::asio::chrono::seconds{2}};

};

1) 添加两个单独的读取和写入处理程序是否有意义,一个用于标题,一个用于正文?

2) 如何确保我可以同时发送和接收数据而不会遇到任何问题?这需要多个套接字吗?这些功能通常是如何实现的?

3) 我将如何发送自定义数据结构?我想实现自定义数据包结构。我将如何发送此类对象,boost 是否具有内置的序列化程序?如何或自定义数据结构发送和接收?

4) 如果在发送或接收数据时连接中断怎么办?此类异常是否通过检查 eof 的错误代码对象直接在接收/发送处理程序中处理?

一个基本的例子会有很大帮助!

最佳答案

1) 添加两个单独的读取和写入处理程序是否有意义,一个用于标题,一个用于正文?

是的。代码不同,不同的处理程序是最佳实践。

2) 如何确保我可以同时发送和接收数据而不会遇到任何问题?

异步操作。函数立即返回,所以唯一的延迟是网络速度。

3) 我将如何发送自定义数据结构?

boost::asio::buffer 支持发送/接收原始内存字节。当这还不够时,asio 有序列化:

4) 如果在发送或接收数据时连接断开会怎样?

所有的读写操作都会返回一个boost::system::error_code。如果发生错误,则必须关闭套接字(并在可能的情况下重新连接)。一些基本代码:

void AfterReadingHeader(const boost::system::error_code & aError)
{
  if (aError)
  {
    // something went wrong 
    boost::system::error_code error;
    socket.shutdown(tcp::socket::shutdown_receive, error);
    socket.close(error);
  }

  ...
}

关于c++ - 使用 boost 异步发送和接收自定义数据包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55676585/

相关文章:

c++ - 在保留顺序的同时从 Vector 中删除元素 - 需要更好的方法

C++ demo编程,混淆类实现

C++:为什么在 Eclipse Neon 中运行的相同代码在 Visual Studio 2013 中会产生不同的输出?

c++ - C2059 : syntax e r r o r : ';'

arrays - 如何并行运行 API 调用 (Node.js)

ios - 在单独的线程上进行 iPhone CoreLocation 调用的最佳方法?

c++ - BOOST_CHECK 无法为自定义类型编译 operator<<

javascript - 与React接口(interface)通信异步加载端

c++ - 在 Qt Creator 中使用 Boost Python

c++ - 编译 boost 程序