我是boost :: asio中异步函数的新手,而我已经在这里遇到了第一个问题:
class tcp_connection
: public boost::enable_shared_from_this<tcp_connection>
{
public:
typedef boost::shared_ptr<tcp_connection> pointer;
static pointer create(boost::asio::io_context& io_context)
{
return pointer(new tcp_connection(io_context));
}
tcp::socket& socket()
{
return socket_;
}
// Called when connection is made
void start()
{
// New connection, read data
boost::array<unsigned char, 128> buf;
boost::asio::async_read(socket_, boost::asio::buffer(buf),
boost::bind(&tcp_connection::handle_readConnection, shared_from_this(), boost::asio::placeholders::error, boost::ref(buf)));
}
private:
tcp_connection(boost::asio::io_context& io_context)
: socket_(io_context)
{
}
void handle_write(const boost::system::error_code& error,
size_t bytes_transferred)
{
}
void handle_readConnection(const boost::system::error_code& error, boost::array<unsigned char, 128> buf)
{
std::cerr << error.message() << std::endl;
std::cout << "New connection!" << std::endl;
}
tcp::socket socket_;
std::string message_;
};
class tcp_server
{
public:
tcp_server(boost::asio::io_context& io_context)
: acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
{
start_accept();
}
private:
// Creates a socket and initializes an async accept operation to wait for a new connection
void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.get_executor().context());
acceptor_.async_accept(new_connection->socket(),
boost::bind(&tcp_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
}
// Called by start_accept. Creates a new connection and runs start_accept again to search for new clients
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code& error)
{
if (!error)
{
new_connection->start();
}
start_accept();
}
tcp::acceptor acceptor_;
};
int main()
{
try {
boost::asio::io_context io_context;
tcp_server server(io_context);
io_context.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
这段代码在main()函数中调用,其目的是从刚刚与其连接的套接字读取一些数据,并打印“ New connection”以及任何错误消息(请参见{{1 }})。现在的问题是,尽管客户端可以连接到它,并且tcp_connection中的tcp_connection::handle_readConnection
行被调用,但boost::asio::async_read
却从未如此。我在这里想念什么吗?预先感谢。
答案 0 :(得分:0)
您实际上连接到远程套接字吗?例如。通过socket::async_connect()
吗?
如果没有,应该从哪里读取数据?
另一个问题在这里:
boost::array<unsigned char, 128> buf;
boost::asio::async_read(socket_, boost::asio::buffer(buf),
boost::bind(&tcp_connection::handle_readConnection, shared_from_this(), boost::asio::placeholders::error, boost::ref(buf)));
您要求asio异步读取堆栈中的缓冲区。 一旦函数返回地址(asio仍存储),该地址将无效,并且读取尝试可能会覆盖堆栈上的任何类型的内存。 从那里开始,您或多或少会遇到未定义的行为,这可能是从未调用回调的原因。 缓冲区必须始终超过读取尝试的持续时间。
生存期必须有效的另一件事是io_ref
。只要任何tcp_connection::pointer
实例处于活动状态,都不得销毁它。由于我们看不到此代码,因此很难说出来。如果它是全局变量或主函数的一部分,则可能没问题。