【问题标题】:When using asio+ssl, the async_write doesn't send the data使用 asio+ssl 时,async_write 不发送数据
【发布时间】:2017-06-07 19:58:44
【问题描述】:

给定:

asio::ssl::stream<asio::ip::tcp::socket&> &m_socket;
async_write(self->m_socket, asio::buffer(self->m_v),
    [self, handler](asio::error_code ec, std::size_t s)
{
    handler(ec);
});

结果: 在发送数据之前调用处理程序(调用 socket.send() 函数)。 结果 2: 数据实际上是在很长一段时间后发送的 - 在我的可重现情况下大约 1 分钟。 因此,事件的顺序如下: 1、async_write被调用; 2. 处理程序被调用; 3. 发送数据。

我认为正确的顺序必须是: 1.async_write被调用; 2.数据发送。 3. 处理程序被调用;

它并不总是发生,但非常可重复。我在整个互联网上搜索了类似的案例 - 一无所获。

我需要建议:该怎么做。它是 asio 中的错误还是我的程序中的一些棘手错误以及在哪里寻找修复它。

我可以轻松重现案例,可以提供日志文件等。

【问题讨论】:

  • 你怎么知道订单是1. 2. 3.而不是1. 3. 2.?您的意思是您测量“3. 数据已接收”而不是“3. 数据已发送”?
  • 1.我在日志消息中添加了时间戳。我在 async_write 之前和其处理程序的开头打印一条日志消息。我根据这些时间戳确定 1 在 2 之前。至于 3,我使用了 Microsoft Message Analyzer 来捕获网络流量。消息分析器捕获还包含时间戳。我相信这些时间戳标记了消息从 asio 代码进入网络系统的时刻。因此,我确定顺序是 1. 2. 3. 2. 当我写“3.发送数据”时,我的意思是发送了数据。
  • 如果您在 MMA 中看到的时间戳晚于 2.,这并不意味着它是在 2. 之后发送的(取决于您在协议中看到时间戳的位置)。这可能只是意味着 MMA 稍后看到了它。此外,像 Nagle 的算法之类的东西也可能在起作用。

标签: c++ network-programming boost-asio


【解决方案1】:

如果您在 MMA 中看到的时间戳晚于 2.,这并不意味着它是在 2. 之后发送的(取决于您在协议中看到时间戳的位置)。这可能只是意味着 MMA 稍后看到了它。此外,像 Nagle 的算法之类的东西也可能在起作用。

尝试设置 TCP NODELAY,例如

socket.open(tcp::v4());
socket.set_option(tcp::no_delay(true));
socket.async_connect(endpoint, handler);

【讨论】:

  • 我相信 MMA 在进入 Windows 网络子系统时会看到该消息,即调用 socket.send 函数时。你能解释一下我为什么不相信吗?
  • 因为 MMA 不在内核中运行,并且所有进程都被公平调度。哪一个获得下一个时间片,哪个核心是不可预测或固定的
  • 在我的设置中可以忽略不计。如果调度是公平的,每个进程都有机会在几毫秒内运行。就我而言,延迟是 50 秒左右。毫秒可以忽略不计。
  • 哦。 50 年代。我不知道为什么我读到了那个。我以为您是在对 ms 计时得出结论。对此感到抱歉。你看过 Nagle/TCP NODELAY 吗?
  • 是的,我做到了(看)。我认为这与这里无关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 2018-09-22
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-01
相关资源
最近更新 更多