我在使用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();
我尝试了两种解决方案:
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);
答案 0 :(得分:1)
我的第一个猜测是你导致ASIO阻止等待完整的i / o完成。这引入了延迟。
对于对延迟敏感的代码,您应始终使用async_read_some()
和async_write_some()
。这些将尽快返回任何部分i / o,以便尽快完成操作系统可以执行的操作。当然,您需要重构代码来处理部分i / o,基本上可以处理每个处理程序调用的任意数量,并保留任何不排除的部分发送或接收缓冲区的任何缓冲区序列,以便下次重试,直到它用完为止。 / p>
我的第二个猜测是你可能正在使用股票。这些引入了延迟。请参阅asio-users邮件列表。
答案 1 :(得分:1)
感谢您的帮助。我找到了答案---我使用调试版运行... 但有些事情仍然很奇怪。
首先,我使用调试模式进行开发。完成开发后,我切换到发布模式并使用“Build Solution”来构建我的dll。我认为dll现在是发布版本所以我开始评估性能。但今天早上,我无意使用“清洁解决方案”,然后使用“构建解决方案”。在构建之后,我再次评估了性能,发现现在几乎所有的延迟都是10毫秒。我想今天早上之前的评估是由带有调试版本的dll完成的。
我仍然不知道“从调试切换到发布和构建解决方案”和“从调试切换到发布并清理解决方案然后构建解决方案”之间的区别。
我会尽力找出差异。
非常感谢您的帮助。