1

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

我的程序流程如下:

客户端使用 async_write 向服务器发送数据,然后它将使用 async_read 从服务器接收数据。所有异步操作的处理程序都是 use_future,超时 = 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();

我尝试了 2 个解决方案:

  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);
4

2 回答 2

1

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

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

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

我会尝试找出不同之处。

非常感谢您的帮助。

于 2017-03-02T11:35:36.877 回答
1

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

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

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

于 2017-03-01T23:05:55.113 回答