1

そう、

Boost asio 関数とソケット (特に非同期読み取り/書き込み) で遊んでいます。さて、ネットワーク接続から新しいバッファーが入ったときにのみハンドラーを呼び出すと思いboost::asio::async_readました...しかし、同じバッファーの読み取りを停止しないため、ハンドラーを呼び出し続けます。転送されたバイト数をチェックすることで軽減できましたが、基本的には CPU サイクルを浪費するビジー待機ループにあります。

ここに私が持っているものがあります:

class tcp_connection : : public boost::enable_shared_from_this<tcp_connection> 
{
public:
    // other functions here

    void start()
    {
    boost::asio::async_read(socket_, boost::asio::buffer(buf, TERRAINPACKETSIZE),
        boost::bind(&tcp_connection::handle_read, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
    }

private:
    const unsigned int TERRAINPACKETSIZE = 128;
    char buf[TERRAINPACKETSIZE];


    void handle_read(const boost::system::error_code& error, size_t bytesT)
    {
        if (bytesT > 0)
        { 
             // Do the packet handling stuff here
        }

        boost::asio::async_read(socket_, boost::asio::buffer(buf, TERRAINPACKETSIZE),
        boost::bind(&tcp_connection::handle_read, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
    }
};

いくつかは切り取られていますが、基本的には新しい接続が作成されてからstart()呼び出されます。handle_readメソッドが継続的に呼び出されないように、私が見逃しているものはありますか?

4

2 に答える 2

6

勝手な推測: チェックインerrorhandle_readますか? 何らかの理由でソケットがエラー状態にある場合、ネストされたasync_readmade fromの呼び出しhandle_readはすぐに「完了」し、すぐに呼び出しが行われると思いますhandle_read

于 2009-10-28T19:16:21.633 に答える
0

私も同じ問題を抱えていました。私の場合、次のようにstd ::vector<unsigned_char>を読み込んでいました。

boost::asio::async_read(socket_,
st::asio::buffer(*message,message->size()),
            boost::bind(
              &ActiveSocketServerSession::handleFixLengthRead,
              shared_from_this(),
              boost::asio::placeholders::error,
              boost::asio::placeholders::bytes_transferred)
    );

さまざまなバイト数を受け入れるための適応ベクトルがあります

    std::vector<unsigned char>* message;
message = new std::vector<unsigned char> (sizePacket);

最初のパケットを受信したときはすべて正常に機能していましたが、最初のパケットの後は、データがない状態でhandle_readerのロック解除を停止することはありません。

私の解決策は、ベクトルを削除し、処理後にスペースを再度割り当てることでした。

void ActiveSocketServerSession::handleFixLengthRead(    const         boost::system::error_code& error,
                                                    std::size_t bytes_transferred){

    --> processing your data (save to another site)
--> delete message;
--> message = new std::vector<unsigned char> (sizePacket);

//starting to read again
boost::asio::async_read(socket_,
                boost::asio::buffer(*message,message->size()),
            boost::bind(
              &ActiveSocketServerSession::handleFixLengthRead,
              shared_from_this(),
              boost::asio::placeholders::error,
              boost::asio::placeholders::bytes_transferred)
);

    }else{
        logMessage.str("");
        logMessage << "Error handling data id: "<<getId()<< "from port";
    }
}

これらの2行を入れた後、すべてうまくいきます。

于 2012-04-20T09:40:39.347 に答える