Я использую неблокирующий TCP-клиент в C ++ и Boost под Ubuntu для отправки данных на TCP-сервер в этом формате std::array<uint8_t, 8> command1;
Это работает очень хорошо, но мне нужно изменить команду1содержание зависит от действий пользователя, поэтому я хотел бы найти решение для непосредственного вызова функции start_connection()
и передачи параметра command1 для отправки его с помощью функции start_write()
.
Как лучше всего это сделатьэто? Есть ли более быстрый и профессиональный способ передачи команды 1 в функцию start_write()
?
std::array<uint8_t, 8> command1;
class client
{
public:
client(boost::asio::io_context& io_context)
: stopped_(false),
socket_(io_context),
deadline_(io_context),
heartbeat_timer_(io_context)
{
}
void start(tcp::resolver::results_type endpoints)
{
// Start the connect actor.
endpoints_ = endpoints;
start_connect(endpoints_.begin());
deadline_.async_wait(boost::bind(&client::check_deadline, this));
}
void stop()
{
stopped_ = true;
boost::system::error_code ignored_ec;
socket_.close(ignored_ec);
deadline_.cancel();
heartbeat_timer_.cancel();
}
private:
void start_connect(tcp::resolver::results_type::iterator endpoint_iter)
{
if (endpoint_iter != endpoints_.end())
{
std::cout << "Trying " << endpoint_iter->endpoint() << "...\n";
// Set a deadline for the connect operation.
deadline_.expires_after(boost::asio::chrono::seconds(10));
// Start the asynchronous connect operation.
socket_.async_connect(endpoint_iter->endpoint(),
boost::bind(&client::handle_connect,
this, _1, endpoint_iter));
}
else
{
// There are no more endpoints to try. Shut down the client.
stop();
}
}
void handle_connect(const boost::system::error_code& ec,
tcp::resolver::results_type::iterator endpoint_iter)
{
if (stopped_)
return;
if (!socket_.is_open())
{
std::cout << "Connect timed out\n";
// Try the next available endpoint.
start_connect(++endpoint_iter);
}
// Check if the connect operation failed before the deadline expired.
else if (ec)
{
std::cout << "Connect error: " << ec.message() << "\n";
socket_.close();
// Try the next available endpoint.
start_connect(++endpoint_iter);
}
// Otherwise we have successfully established a connection.
else
{
std::cout << "Connected to " << endpoint_iter->endpoint() << "\n";
// Start the heartbeat actor.
start_write(1);
}
}
EDIT1: по какой-то причине ранее опубликованный код был неполным. Это недостающая часть:
void start_write(int scelta)
{
if (stopped_)
return;
if (scelta == 1){
command1 = {0x58, 0x01, 0x11, 0x00, 0x00, 0x00, 0x10, 0x7A};
}
// Start an asynchronous operation to send a heartbeat message.
boost::asio::async_write(socket_, boost::asio::buffer(command1, 8), boost::bind(&client::handle_write, this, _1));
}
void handle_write(const boost::system::error_code& ec)
{
if (stopped_)
return;
if (!ec)
{
printf("Pacchetto inviato\n");
stop();
}
else
{
std::cout << "Error on heartbeat: " << ec.message() << "\n";
stop();
}
}
void check_deadline()
{
if (stopped_)
return;
if (deadline_.expiry() <= steady_timer::clock_type::now())
{
socket_.close();
deadline_.expires_at(steady_timer::time_point::max());
}
// Put the actor back to sleep.
deadline_.async_wait(boost::bind(&client::check_deadline, this));
}
private:
bool stopped_;
tcp::resolver::results_type endpoints_;
tcp::socket socket_;
std::string input_buffer_;
steady_timer deadline_;
steady_timer heartbeat_timer_;
};
int start_connection(){
try
{
boost::asio::io_context io_context;
tcp::resolver r(io_context);
client c(io_context);
c.start(r.resolve("192.168.1.4", "3000"));
io_context.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
}
int main(int argc, char* argv[])
{
start_connection();
return 0;
}