【问题标题】:C++ boost::asio::async_write send problemsC++ boost::asio::async_write 发送问题
【发布时间】:2014-05-26 21:56:30
【问题描述】:

当我调用async_write() 时,远程对等方不会接收数据,直到我再次调用async_write()。比如我有3个包,abc

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

【问题讨论】:

  • 你有另一个线程服务于 io 服务吗?否则,组合函数将不得不等待。如何保护套接字免受冲突访问?我没有看到你使用股线。 (您似乎希望操作“以某种方式”完成,而实际上没有任何代码来完成它。)
  • 每个套接字使用 1 个 io_service,我从池中获取,如下所示:pastebin.com/F4TSSEBA。所以每个会话都在 1 个线程内。
  • 那么当线程在做其他事情时,套接字就无法向前推进。此外,在前一个 async_write 完成之前,您不能调用 async_write -- 否则这两个操作可以交错。
  • 为什么线程会做其他事情?问题不存在,当我想发送第二个数据包时,确实是发送了第一个数据包。
  • 我认为套接字只是在缓冲。另外,如果复制 SendPacket 会导致未定义的行为,您可能没有为这种类型正确实施 Rule-Of-Three?

标签: c++ boost boost-asio


【解决方案1】:

当少量数据被写入套接字时,例如在原始代码中(12 字节~),由于Nagle's algorithm,通常会观察到在后续数据写入套接字之前不会发送数据的行为.简而言之,许多系统将尝试通过将小的出站消息连接成单个消息然后发送来缓解 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 可能会导致更高的吞吐量。然而,仍然值得进一步检查应用程序协议和逻辑,以确定何时或哪些数据可以被缓冲,以及何时需要立即发送。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 2012-08-12
    • 2021-03-01
    相关资源
    最近更新 更多