0

ブースト asio ライブラリを使用してネットワーク プログラミングを実装しようとしています。これは、何らかのデータ (「##」で終わる) がエンドポイントに到着したときに呼び出されるコードです。

{
    boost::asio::async_read_until(m_socket, m_response,
                std::string("##"),
                boost::bind(&CTcpClient::HandleReceive,
                                shared_from_this(),
                                boost::asio::placeholders::error,
                                boost::asio::placeholders::bytes_transferred));

}


void CTcpClient::HandleReceive(const ErrorCodeType p_errorCode, size_t p_length)
{
    IN_FUNCTION

    if ( !p_errorCode )
    {
        logInfo(STR("Data received ..."));

        boost::asio::async_read_until(m_socket, m_response,
            std::string("##"),
            boost::bind(&CTcpClient::HandleReceive,
                            shared_from_this(),
                            boost::asio::placeholders::error,
                            boost::asio::placeholders::bytes_transferred));

        m_onReceiveSignal(sbuf2s(m_response));

    }
    else
    {
        Shutdown(p_errorCode);
    }

    OUT_FUNCTION
}

エンドポイントに送信されるデータが「KINGS##」であるとしましょう。したがって、Handlereceive は 1 回呼び出す必要があります。しかし、私のコードでは、これは 2 回呼び出されています。1 回は "KINGS##" で、もう 1 回は null 文字列です。

誰かが理由とそれを修正する方法を教えてもらえますか?

4

2 に答える 2

1

m_response読み取りが成功した後、トークンまでバッファをクリアする必要があります。

非同期読み取りを再発行する前にこれを行っていないため、応答バッファーにはまだ##文字が含まれているため、読み取りはすぐに完了します。

補足として、async_read_until呼び出しは ## を超えてデータを読み取る可能性があるため、## までを含めて消去するように注意する必要があります。

于 2013-04-12T19:11:21.483 に答える
0

m_onReceiveSignal(...) の後に async_read_until(...) を呼び出すだけでよいと思います。Handlereceive 内で両方の順序を変更します。

これは、Handlereceive を初めて呼び出すのは、async_read_until(...) を介して別のメソッド (おそらく接続) からのものであるという前提の下にあります。

于 2017-11-13T22:54:46.710 に答える