通过boost异步发送和接收自定义数据包? [英] Async sending and receiving custom data packets with boost?

查看:307
本文介绍了通过boost异步发送和接收自定义数据包?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过boost异步发送和接收自定义数据包,基于当前的实现,我有一些疑问:

I am trying to asynchronously send and receive custom data packets with boost and I have some questions, based on my current implementation:

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)添加两个用于读写的单独的处理程序是否有意义,一个用于标题,一个为了身体?

1) Would it make sense to add two seperate handlers for reading and writing, one for the header one for the body?

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

2) How can I ensure that I can send and receive data at the same time without running into any issues? Does this require multiple sockets? How is such functionality usually implemented?

3)我将如何发送自定义数据结构?我想实现一个自定义的数据包结构。我将如何发送此类对象,boost是否具有内置的串行器?

3) How would I go sending custom data structures? I want to implement a custom packet structure. How would I sent such objects, does boost have an inbuilt serializer? How or custom data structures sent and received?

4)如果在发送或接收数据期间连接断开,会发生什么情况?通过检查eof的错误代码对象是否可以在接收/发送处理程序中直接处理此类异常?

4) What happens if the connection drops during sending or receiving data? Are such exceptions handled directly in the receive/send handlers by checking the errorcode object for eof?

一个基本示例将大有帮助!

A basic example for that would help a lot!

推荐答案

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

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

Yes. Code is different, different handlers is best practice.

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

异步操作。函数会立即返回,因此唯一的延迟就是网络速度。

Async operations. The functions return immediately, so the only delay is the network speed.

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

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

boost::asio::buffer supports sending/receiving raw memory bytes. When this isn't enough, asio has serialization:

  • https://www.boost.org/doc/libs/1_70_0/libs/serialization/doc/index.html
  • https://www.boost.org/doc/libs/1_70_0/libs/serialization/example/demo.cpp

4)如果在发送或接收数据期间连接断开,会发生什么?

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

All read and write operations return a boost::system::error_code. If an error occurs, the socket must be closed (and connected again if possible). Some basic 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);
  }

  ...
}

这篇关于通过boost异步发送和接收自定义数据包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆