我正在为Orbiter space simulator编写一个DLL插件。 ,它允许与外部系统进行 UDP 通信。我选择 boost::asio 来完成这项任务,因为它允许我从低级内容中抽象出来。
“边界条件”如下:
- 我可以从我的 DLL 创建任何线程或调用任何 API 函数
- 由于缺乏其他线程安全性,我只能在传递给 DLL(每帧)的回调内修改模拟内部的数据。
因此,我为用于通信的 NetworkClient 类选择了以下架构:
- 构建后,它会初始化 UDP 套接字 (boost::socket+boost::io_service) 并启动一个线程,该线程调用 io_service.run()
- 传入消息异步放入队列(通过 CriticalSection 实现线程安全)
- 回调处理函数可以从队列中拉取消息并进行处理
但是,我在运行实现时遇到了一些奇怪的异常: boost::exception_detail::clone_impl > 位于内存位置 0x01ABFA00。
io_service.run()调用时出现异常。
有人可以指点我吗,我错过了什么吗?我的类(class)的代码 list 如下。
网络客户端声明:
class NetworkClient {
public:
NetworkClient(udp::endpoint server_endpoint);
~NetworkClient();
void Send(shared_ptr<NetworkMessage> message);
inline bool HasMessages() {return incomingMessages.HasMessages();};
inline shared_ptr<NetworkMessage> GetQueuedMessage() {return incomingMessages.GetQueuedMessage();};
private:
// Network send/receive stuff
boost::asio::io_service io_service;
udp::socket socket;
udp::endpoint server_endpoint;
udp::endpoint remote_endpoint;
boost::array<char, NetworkBufferSize> recv_buffer;
// Queue for incoming messages
NetworkMessageQueue incomingMessages;
void start_receive();
void handle_receive(const boost::system::error_code& error, std::size_t bytes_transferred);
void handle_send(boost::shared_ptr<std::string> /*message*/, const boost::system::error_code& /*error*/, std::size_t /*bytes_transferred*/) {}
void run_service();
NetworkClient(NetworkClient&); // block default copy constructor
};
方法实现:
NetworkClient::NetworkClient(udp::endpoint server_endpoint) : socket(io_service, udp::endpoint(udp::v4(), 28465)) {
this->server_endpoint = server_endpoint;
boost::thread* th = new boost::thread(boost::bind(&NetworkClient::run_service,this));
start_receive();
}
void NetworkClient::start_receive()
{
socket.async_receive_from(boost::asio::buffer(recv_buffer), remote_endpoint,
boost::bind(&NetworkClient::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)
);
}
void NetworkClient::run_service()
{
this->io_service.run();
}
最佳答案
据我所知,您的架构没有任何问题。您应该捕获从 io_service::run() 抛出的异常,这可能是问题的根源。
void NetworkClient::run_service()
{
while(1) {
try {
this->io_service.run();
} catch( const std::exception& e ) {
std::cerr << e.what << std::endl;
}
}
}
您还需要修复引发异常的任何内容。
关于c++ - 在单独的线程中正确使用 Boost::asio,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14304660/