|
Boost Users : |
From: Maria Tirindelli (maria.tirindelli_at_[hidden])
Date: 2024-03-06 12:42:44
I am experiencing an issue with boost 1.74 on linux. I am trying to have a server that asynchronously reads data from a tcp socket, and then closes when the client disconnect. My code looks like:
class SimpleTCPServerTest::SocketHandler {
public:
explicit SocketHandler(boost::asio::ip::tcp::socket inputSocket
) : socket(std::move(inputSocket)) {
socket.set_option(boost::asio::socket_base::keep_alive(true));
}
boost::asio::ip::tcp::socket socket;
};
SimpleTCPServerTest::SimpleTCPServerTest(std::string address, int port) :
m_address(std::move(address)), m_port(port), m_ioc(boost::asio::io_context(1)),
m_acceptor(boost::asio::ip::tcp::acceptor(m_ioc)),
readTimer(m_ioc){
std::vector<char> buffer_data(1024);
this->m_buffer = boost::asio::buffer(buffer_data);
}
bool SimpleTCPServerTest::open() {
//auto const address = boost::asio::ip::make_address(ip);
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), static_cast<unsigned short>(m_port));
boost::system::error_code ec;
// Open the acceptor
m_acceptor.open(endpoint.protocol(), ec);
if (ec) {
LOG_ERROR("SimpleTCPServerTest", "Failed to open acceptor: " << ec.message());
return false;
}
// Allow address reuse
m_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec);
if (ec) {
LOG_ERROR("SimpleTCPServerTest", "Failed to set reuse option in acceptor: " << ec.message());
return false;
}
// Bind to the server address
m_acceptor.bind(endpoint, ec);
if (ec) {
LOG_ERROR("SimpleTCPServerTest", "Failed to bind acceptor: " << ec.message());
return false;
}
// Start listening for connections
m_acceptor.listen(boost::asio::socket_base::max_listen_connections, ec);
if (ec) {
LOG_ERROR("SimpleTCPServerTest", "acceptor failed to start listening: " << ec.message());
return false;
}
m_acceptor.async_accept(boost::asio::make_strand(m_ioc),
[this](boost::system::error_code ec, boost::asio::ip::tcp::socket socket) {
on_accept(ec, std::move(socket));
});
m_iocRunThread = boost::thread([this] {
m_ioc.run();
ââââââLOG_INFO("Exiting run thread");
});
return true;
}
}
void SimpleTCPServerTest::on_accept(boost::system::error_code ec, boost::asio::ip::tcp::socket socket) {
LOG_INFO("Client is connected");
m_socketHandler = std::make_unique<SocketHandler>(std::move(socket));
read();
}
void SimpleTCPServerTest::read() {
LOG_INFO("SimpleTCPServerTest", "Waiting a new message");
readTimer.expires_from_now(boost::posix_time::milliseconds(50));
readTimer.async_wait([this](boost::system::error_code ec) {
LOG_INFO("Timer expired");
if (ec != boost::asio::error::operation_aborted)
return;
LOG_INFO("Timer expired with error");
m_socketHandler->socket.cancel(); });
m_socketHandler->socket.async_read_some(m_buffer,
[this](const boost::system::error_code error, // Result of operation.
std::size_t bytes_transferred) {
if (error)
{
LOG_INFO("Client disconnected: " << error.message());
signalReadyToStop.emitSignal();
ââââââââââââââââââââââââââââââââââââ// HERE IT CRASHES
return;
}
std::string dataString(boost::asio::buffer_cast<const char*>(m_buffer), bytes_transferred);
LOG_INFO("Data was received: Size: " << bytes_transferred << " " << dataString);
// Reset the buffer
std::vector<char> buffer_data(1024);
this->m_buffer = boost::asio::buffer(buffer_data);
this->read();
});
}
SimpleTCPServerTest::~SimpleTCPServerTest() {
LOG_INFO("Terminating");
readTimer.cancel();
m_acceptor.cancel();
m_socketHandler->socket.cancel();
m_ioc.stop();
m_iocRunThread.join();
}
The client is a simple python client that sends a few messages before disconnecting. my main.cpp is like:
std::atomic<bool> m_runFlag = true;
SimpleTCPServerTest server;
server.signalReadyToStop.connect([&m_runFlag](){
m_runFlag =false;
});
server.open();
while(m_runFlag)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
LOG_INFO("Exiting test");
}
The problem is that the code always crashes when returning from the async_read (indicated with "HERE IT CRASHES COMMENT") with error SIGABRT tcache_thread_shutdown(): unaligned tcache chunk detected. Even if I remove the return statement there, I still have the crash when calling m_ioc.stop(). It seems the error occurs when exiting from the m_iocRunThread (the "Exiting run thread" log is executed)
What am I doing wrong?
Thanks everyone
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net