【问题标题】:boost asio async_read delay (local socket)提升 asio async_read 延迟(本地套接字)
【发布时间】:2017-07-20 20:23:48
【问题描述】:

我在使用 boost asio 进行套接字编程时遇到问题。

我的程序流程如下:

客户端使用 async_write 向服务器发送数据,然后它会使用 async_read 从服务器接收数据。所有异步操作的handler都是use_future,timeout = 2秒。

问题是:

服务器的处理时间约为 10 毫秒。服务器和客户端都在同一台计算机上,因此客户端应该在服务器发送数据时接收数据。但是,我测量了 async_read 的延迟,发现其中一些约为 10 毫秒,而另一些约为 30 ~ 40 毫秒。通常,它们是交错的。

我如何衡量:

auto start_time = std::chrono::steady_clock::now();

auto read_result = async_read(..., use_future);
auto read_future_status = read_result.wait_for(timeout);

auto end_time = std::chrono::steady_clock::now();

我尝试了两种解决方案:

  1. 为 boost::asio::streambuf 分配更大的空间。我分配了 4096 字节,我的数据大小从未超过 1500 字节,但它不起作用。
  2. 使用socket_.set_option(ip::tcp::no_delay(true)); 关闭Nagle 的算法和延迟确认。此外,它无法正常工作。

我不知道这个问题。任何人都可以帮助我吗?请...

更新:这是我的部分源代码

下面是向服务器发送请求的代码:

auto send_result = async_write(input_socket, out_buffer, use_future);
auto send_status = send_result.wait_for(std::chrono::seconds(timeout));
if(send_status == std::future_status::timeout)
{
    LOG4CPLUS_ERROR_FMT(logger_, "send %s future error : (%d).", action, send_status);
}

out_buffer.consume(request.length());

下面是从服务器接收数据的代码。

auto read_buffer_result = async_read(output_socket, in_buffer, transfer_exactly(sizeof(Header)), use_future);
auto read_status = read_buffer_result.wait_for(std::chrono::seconds(timeout));
if(read_status == std::future_status::timeout)
{
    LOG4CPLUS_ERROR_FMT(logger_, "read %s header future error : (%d).", action, read_status);
}
size_t byte_transferred = read_buffer_result.get();
in_buffer.consume(byte_transferred);

【问题讨论】:

  • 如果您提供更多代码会有所帮助
  • ...甚至是一个完整的(简短的!)示例
  • 感谢您的回复。我将尝试发布源代码。
  • 每一个询问为什么某些东西不起作用的好问题都包含一个 MCVE。 MCVE 应该是一个 cpp 文件,其中包含 main() 函数,这会显示问题。我们可以简单地剪切并粘贴到 ide 中进行检查。

标签: c++ sockets boost latency asio


【解决方案1】:

我的第一个猜测是您导致 ASIO 阻塞等待完整 i/o 完成。这会引入延迟。

对于延迟敏感的代码,您应该始终使用async_read_some()async_write_some()。这些将尽快返回任何部分 i/o,以便您尽可能快地完成操作系统可以做的事情。当然,您需要重构代码以处理部分 i/o,基本上每次处理程序调用尽可能多地处理,并保留任何未排水的部分发送或接收缓冲区的任何缓冲区序列,以便下次重试,直到用完为止。

我的第二个猜测是您可能正在使用股线。这些引入了延迟。请参阅 asio-users 邮件列表。

【讨论】:

    【解决方案2】:

    感谢您的帮助。我找到了答案---我使用调试版本来运行... 但还是有些奇怪。

    起初,我使用调试模式进行开发。完成开发后,我切换到发布模式并使用“构建解决方案”来构建我的 dll。我认为现在的 dll 是发布版本,所以我开始评估性能。但是今天早上,我无意使用“清洁解决方案”然后“构建解决方案”。构建完成后,我再次评估性能,发现现在几乎所有的延迟都是 10 毫秒。我猜今天早上之前的评估是由带有调试版本的dll完成的。

    我仍然不知道“从调试切换到发布并构建解决方案”和“从调试切换到发布并清理解决方案然后构建解决方案”之间的区别。

    我会尝试找出不同之处。

    非常感谢您的帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-05
      • 2018-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多