2

私はLacewinghttp://lacewing-project.org/と呼ばれるサーバーおよびクライアントクラスでTCPライブラリを使用しています

クライアントにいくつかの個別のメッセージを送信すると、それらがバンドルされることがあり、それらを分離する唯一の方法は、それらを再度解析することであることに気付きました。ただし、バイナリデータを送信する場合、解析は非常に困難です。

なぜそれがこれを行うのか誰かが知っていますか?クライアントとサーバーの両方でDisableNagling()を試しましたが、それでも実行されます。

これが私が送るかもしれない何かの例です:

void ServerCore::loginRequestC( const std::string& userName, const std::string& password )
{
    std::cout << "Got request" << std::endl;
    ServerPlayer* player = (ServerPlayer*)getServerClient()->Tag;
    player->setUsername(userName);

    for (size_t i = 0; i < m_players.size(); ++i)
    {
        if(m_players[i] != player)
        {
            std::cout << "Telling new about " << m_players[i]->getUsername() << std::endl;
            m_enc.playerJoinedS(m_players[i]->getUsername());
            player->getClient()->Send(m_enc.getLastMessage().c_str());
        }
    }

    m_enc.loginResultS(true,"");

    player->getClient()->Send(m_enc.getLastMessage().c_str());

    m_enc.playerJoinedS(userName);
    for (size_t i = 0; i < m_players.size(); ++i)
    {
        if(m_players[i] != player)
        m_players[i]->getClient()->Send(m_enc.getLastMessage().c_str());
    }

}

だから私が持っているつもりだった場合:

MSG_A
MSG_B
MSG_C

送信する可能性があります:

MSG_A
MSG_BMSG_C

メッセージはランダムにまとめられます。問題なのは私のコードではありません。確認しました。

メッセージをバンドルすることは便利ですが、ライブラリではなく、いつ発生するかを制御したいと思います。

ありがとう

4

2 に答える 2

7

これはライブラリではなく、それを実行しているTCPプロトコル自体です。TCPソケットは、バイトの双方向ストリームです。1回の書き込みで、反対側で複数の読み取りが発生する可能性があり、その逆も同様です。

そのストリームをメッセージに簡単に分割できるように、アプリケーションレベルのプロトコルを設計する必要があります。一般的なアプローチは、長さプレフィックスまたはメッセージ区切り文字を使用することです。

于 2012-05-24T19:34:54.767 に答える
2

TCPはストリーム指向のプロトコルであるため、メッセージ境界が組み込まれていません。ストリームをメッセージに分割する必要があります。

反対のUDPはデータグラムプロトコルであり、各パケットには個別のメッセージがあります。欠点は、信頼性が低いことです。

于 2012-05-24T19:34:21.900 に答える