Я пытался создать приложение для обмена сообщениями, используя Boost :: asio, и по какой-то причине моя модифицированная версия chat_client не получает никаких сообщений. Сначала я подумал, что io_context
заканчивается обработчиками, но это не так. Странно, если я исключу контроллер. cpp и создам объект chat_client в основном, мои проблемы решены.
chat_client. cpp (модифицировано из примеров) Я жестко запрограммировал IP моего сервера и порт для тестирования
#include <string.h>
#include <string>
#include "chat_client.h"
using asio::ip::tcp;
typedef std::deque<chat_message> chat_message_queue;
chat_client::chat_client(std::string ip, std::string port)
: socket_(io_context_)
{
tcp::resolver resolver(io_context_);
endpoints = resolver.resolve(ip, port);
do_connect(endpoints);
t = new std::thread([this](){ io_context_.run(); });
}
chat_client::~chat_client()
{
t->join();
}
void chat_client::write(const chat_message& msg)
{
asio::post(io_context_,
[this, msg]()
{
bool write_in_progress = !write_msgs_.empty();
write_msgs_.push_back(msg);
if (!write_in_progress)
{
do_write();
}
});
}
void chat_client::close()
{
asio::post(io_context_, [this]() { socket_.close(); });
}
void chat_client::do_connect(const tcp::resolver::results_type& endpoints)
{
asio::async_connect(socket_, endpoints,
[this](std::error_code ec, tcp::endpoint)
{
if (!ec)
{
do_read_header();
}
});
}
void chat_client::do_read_header()
{
asio::async_read(socket_,
asio::buffer(read_msg_.data(), chat_message::header_length),
[this](std::error_code ec, std::size_t /*length*/)
{
if (!ec && read_msg_.decode_header())
{
do_read_body();
}
else
{
socket_.close();
}
});
}
void chat_client::do_read_body()
{
asio::async_read(socket_,
asio::buffer(read_msg_.body(), read_msg_.body_length()),
[this](std::error_code ec, std::size_t /*length*/)
{
if (!ec)
{
std::cout.write(read_msg_.body(), read_msg_.body_length());
std::cout << "\n";
do_read_header();
}
else
{
socket_.close();
}
});
}
void chat_client::do_write()
{
asio::async_write(socket_,
asio::buffer(write_msgs_.front().data(),
write_msgs_.front().length()),
[this](std::error_code ec, std::size_t /*length*/)
{
if (!ec)
{
write_msgs_.pop_front();
if (!write_msgs_.empty())
{
do_write();
}
}
else
{
socket_.close();
}
});
}
контроллера. cpp
#include <stdexcept>
#include "controller.h"
//#include "chat_client.h" inside controller.h
/*Constructor*/
Controller::Controller() {}
void Controller::execute_cmd(int cmd)
{
switch(cmd)
{
case 1: //Create chat_client
{
try
{
c = new chat_client("192.168.0.11", "5000");
chat_message msg;
msg.body_length(5);
std::memcpy(msg.body(), "test", msg.body_length());
msg.encode_header();
c->write(msg);
}
catch(std::runtime_error& e)
{
std::cerr << "Cannot create chat_client" << std::endl;
}
}
case 2: //Close chat_client
{
c->close();
delete c;
}
case 3: //TESTING
{
char line[chat_message::max_body_length + 1];
while (std::cin.getline(line, chat_message::max_body_length + 1))
{
chat_message msg;
msg.body_length(std::strlen(line));
std::memcpy(msg.body(), line, msg.body_length());
msg.encode_header();
c->write(msg);
}
}
}
}
main. cpp используется для тестирования
#include "controller.h"
int main(int argc, char** argv)
{
Controller c;
c.execute_cmd(1); //create chat_client
c.execute_cmd(2); //Start sending messages
return 0;
}