c++ boost::asio::async_write发送问题

C++ boost::asio::async_write send problems

本文关键字:write 问题 async boost asio c++      更新时间:2023-10-16

当我调用async_write()时,远端对等端没有接收到数据,直到我再次调用async_write()。例如,我有3个数据包,a, bc:

SendPacket(a); // the remote side receives nothing
SendPacket(b); // the remote side receives packet a
SendPacket(c); // the remote side receives packet b

这是我发送的代码:

void Session::SendPacket(packet p)
{
    dword len = p.Lenght(); 
    byte* buffer_send = new byte[len + 4]; //4 cause of the header
    memcpy(buffer_send + 4, p.GetRaw(), len); // copy everything to the buffer +4, 0-4 is header
    m_codec.EncodePacket(buffer_send, len);
    boost::asio::async_write(m_socket, boost::asio::buffer(buffer_send, len + 4),
                boost::bind(&Session::OnPacketSend, this, len + 4, boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred, buffer_send));
}
void Session::OnPacketSend(int len, const boost::system::error_code &e, size_t bytes_transferred, byte* buf)
{
    // this asynchronously fires when packet data is sent
    delete[] buf;
    if (e || bytes_transferred != len)
    {
        Stop();
        return;
    }
}

我这样使用它:

packet pp;
pp.WriteWord(0);
pp.WriteDword(4);
pp.WriteWord(0);
SendPacket(pp);

同样,当SendPacket()通过值而不是引用接受packet时,会发生崩溃。

Gr

当少量数据写入套接字时,例如在原始代码中(12字节~),由于Nagle的算法,通常会观察到数据在后续数据写入套接字之前不被发送的行为。简而言之,许多系统将尝试通过将小的出站消息连接成单个消息然后发送来缓解IP/TCP拥塞。要在每个套接字的基础上显式禁用此行为,请设置boost::asio::ip::tcp::no_delay选项:

boost::asio::ip::tcp::socket socket(io_service);
// ...
boost::asio::ip::tcp::no_delay option(true);
socket.set_option(option);

如果有足够的带宽,禁用Nagle可能会导致更高的吞吐量。然而,为了确定何时或哪些数据可以被缓冲,以及何时需要立即发送数据,仍然值得更多地检查应用程序协议和逻辑。