1

外部システムとの UDP 通信を可能にするOrbiter space simulator用の DLL プラグインを作成しています。低レベルのものから抽象化できるため、タスクにboost::asioを選択しました。

「境界条件」は次のとおりです。

  1. 任意のスレッドを作成したり、DLL から任意の API 関数を呼び出したりできます
  2. 他のスレッド セーフがないため、DLL (各フレーム) に渡されたコールバック内でのみシミュレーション内のデータを変更できます。

したがって、通信に使用している NetworkClient クラスに次のアーキテクチャを選択しました。

  • 構築時に、UDP ソケット (boost::socket+boost::io_service) を初期化し、io_service.run() を呼び出すスレッドを開始します。
  • 着信メッセージは非同期でキューに入れられます (CriticalSection によるスレッドセーフ)。
  • コールバック処理関数は、キューからメッセージを取得して処理できます

ただし、実装を実行すると奇妙な例外が発生しました: boost::exception_detail::clone_impl > at memory location 0x01ABFA00.

例外は io_service.run() 呼び出しで発生します。

誰か教えてください。私のクラスのコード リストは以下のとおりです。

NetworkClient 宣言:

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();
}
4

1 に答える 1

1

私が見ることができるアーキテクチャに問題はありません。からスローされた例外をキャッチする必要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;
        }
    }
}

また、例外をスローしているものをすべて修正する必要があります。

于 2013-01-13T17:07:43.043 に答える