TCP库捆绑消息?

时间:2012-05-24 19:29:25

标签: c++ api tcp

我正在使用一个名为Lacewing http://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

消息随机捆绑在一起。这不是我的代码问题。我查过了。

虽然捆绑邮件很有用,但我想控制它何时发生,而不是库。

由于

2 个答案:

答案 0 :(得分:7)

这不是库,而是TCP协议本身就是这样做的。 TCP套接字是双向字节流。一次写入可能导致另一侧的多次读取,反之亦然。

您必须设计应用程序级协议,以便将该流拆分为消息。常见的方法是使用长度前缀或消息分隔符。

答案 1 :(得分:2)

TCP是面向流的协议,因此它没有构建消息边界。您需要自己将流拆分为消息。

相反的UDP是数据报协议,每个数据包都有一个单独的消息。缺点是它不可靠。