0

我正在尝试为我们的基础架构开发内部扫描仪,当时我已经开始研究 boost asio 以启动 254 连接。

我在 boost asio 文档中没有找到任何可以为我指明正确方向的示例。

我想创建一个对象的 254 个实例,每个实例都使用 async_read_until 连接和读取,使用 io_service。

从 boost 中使用多个 tcp::resolver 和多个 tcp::socket 的正确方法是什么(理想情况下每个类一个?)

我还看到一些关于解析器和插座不可移动的投诉

我有非常基本的代码,不太确定下一步该去哪里……我将不胜感激。谢谢。

主.cpp:

#include <cstdlib>
#include <iostream>
#include <vector>
#include <thread>

#include <boost/asio.hpp>

#include "Harvester.hpp"

int main(int argc, char* argv[]) {

    if (argc != 2) {
        std::cerr << "Usage: harvest <range> IE: 10.30.0" << std::endl;
        return EXIT_FAILURE;
    }

    boost::asio::io_service io_service;

    // Launch the io_service thread ...
    std::thread t([&io_service]() { io_service.run(); });

    // do a bunch of stuff
    std::string range(argv[1]);
    std::cout << "Range is " << range << std::endl;
    // Build up a list of harvester
    std::string tempRange;

    std::vector<Harvester> harvesters;
    //harvesters.reserve(254);

    for (int x=1; x<255; x++) {
        tempRange = range + "." + std::to_string(x);
        std::cout << "Going to harvest " << tempRange << std::endl;
        harvesters.emplace_back( io_service );
    }
    t.join();
    return EXIT_SUCCESS;
}

收割机.hpp:

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

using boost::asio::ip::tcp;

class Harvester {
    public:
        Harvester(boost::asio::io_service &io_service);
        Harvester(const Harvester&&); // move constructor..
        void connectTo(std::string &ip);
        void doRead();
        void closeConnection();
    private:
        std::string receivedData;
        boost::asio::io_service &io_service_;
        //tcp::resolver resolver;
        tcp::socket socket_;
};

收割机.cpp

#include "Harvester.hpp"

Harvester::Harvester(boost::asio::io_service &io_service) : io_service_(io_service), socket_(io_service) {

}

// This is for the emplace_back? Create a new object and move into the vector (this break everything big time)
Harvester::Harvester(const Harvester&& other) {
    io_service_ = other.io_service_;
    socket_ = other.socket_;
}

void Harvester::connectTo(std::string &ip) {

}
4

1 回答 1

0

没有不必要的细节,以下是我会做的:

为了Harvester

class Harvester : public std::enable_shared_from_this<Harvester> {
 public:
  ~Sender() = default;

  template<typename... Args>
  static std::shared_ptr<Harvester> Create(Args&&... args) {
    return std::shared_ptr<Harvester>(new Harvester(std::forward<Args>(args)...));
  }

  void ConnectTo(const std::string& ip_address) {
    ...
    socket_.async_connect(
        endpoint,
        [self = shared_from_this()]
        (const boost::system::error_code&, size_t) {
          // possibly write/read?
        });
  }

  void DoRead() {
    ...
    socket_.async_receive(
        read_buffer_,
        [self = shared_from_this()]
        (const boost::system::error_code&, size_t) {
          // data handling
        });
  }

  void CloseConnection() {
    boost::system::error_code ec;
    socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
    socket_.close(ec);
  }

 private:
  Harvester(boost::asio::io_service& io_service) : socket_(io_service) {}
  Harvester(const Harvester&) = delete;
  Harvester(Harvester&&) = delete;
  Harvester& operator=(const Harvester&) = delete;
  Harvester& operator=(Harvester&&) = delete;

  SocketType socket_;
  MutableBuffer read_buffer_;
}

对于main(忽略线程或简单的异步)

...
std::vector<Harvester> harvesters;
harvesters.reserve(254);
for (int i = 0; i < 254; ++i) {
  ...
  auto harvester = Harvester::Create(io_service);
  harvester->ConnectTo(...);  // or however you want to trigger the action
  harvesters.emplace_back(std::move(harvester));
}
...
for (const auto& harvester : harvesters)  // unless you've handled it already
  harvester->CloseConnection();
...

在您了解隐藏在下面的内容之前,不要担心可移动性。例如,套接字是一个描述符。你想在移动中复制它,还是简单地复制它

Socket(Socket&& other) : sd_(other.sd_) { other.sd_ = -1; }

一切都取决于您尝试实现的目标。

脚注:为了emplace_back按预期工作,需要声明对象的移动构造函数noexcept

于 2017-08-17T01:40:29.720 回答