Ускорить связь один ко многим
Я пытаюсь разработать внутренний сканер для нашей инфраструктуры, и я начал изучать boost asio для запуска соединения 254 в то время.
Я не нашел ни одного примера в документации по boost asio, который бы указывал мне правильное направление.
Я хотел бы создать 254 экземпляра объекта, каждый из которых подключался бы и читал, используя async_read_until, используя io_service.
Каков был бы правильный подход для использования нескольких tcp::resolver и нескольких tcp::socket от boost (в идеале по одному на класс?)
Также я вижу некоторые жалобы на резольвер и сокет
У меня очень простой код, и я не очень уверен, куда идти дальше... Буду признателен за любые замечания. Благодарю.
main.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;
}
harvester.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_;
};
Harvester.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) {
}
1 ответ
Без лишних деталей я бы сделал следующее:
За 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
,