gpt4 book ai didi

c++ - Boost asio http截止日期错误?

转载 作者:太空宇宙 更新时间:2023-11-04 11:37:32 25 4
gpt4 key购买 nike

下面的代码主要是 HTTP 客户端示例,只有很少的更改以支持下载截止时间。

它按预期工作,但在极少数情况下,例如如果互联网不稳定,它不起作用并且截止日期可以超过我设置的时间(我设置 10 时 20 秒或更多)。这种情况很少发生,我无法重现,它发生在我意想不到的时候。

为了避免发布大量行(因为很少有人会阅读它们),这里是我认为错误所在的地方:

deadline_.expires_from_now(boost::posix_time::milliseconds(deadline));

tcp::resolver::query query(server, "http");
resolver_.async_resolve(query,
boost::bind(&client::handle_resolve, this,
boost::asio::placeholders::error,
boost::asio::placeholders::iterator));

deadline_.async_wait(boost::bind(&client::check_deadline, this));

这些行的顺序是否正确?

这里是检查截止日期函数:

void check_deadline()
{
if(deadline_cancelled)
return;
else if (deadline_.expires_at() <= deadline_timer::traits_type::now())
socket_.close();
else
deadline_.async_wait(boost::bind(&client::check_deadline, this));
}

最佳答案

您也应该在截止日期计时器上使用 async_wait()。如果您不这样做,您将不会收到通知,您只需检查(事后)时间是否已经到期。

然后如果它完成了(ec 而不是 operation_aborted)那么你应该

  • cancel() 套接字上的异步操作
  • 可选择关闭套接字

附言。嗯。/似乎/你正在做类似的事情,虽然不清楚在哪里

  • deadline_cancelled 来自
  • 为什么不接受 deadline_.async_await
  • 的完成处理程序中的 error_code
  • 为什么您要手动处理时间比较,而不是相信完成处理程序会如其所言

更新 这是执行 HTTP 请求的完整示例。事实上,它从 http://www.angio.net/pi/digits.html 下载了百万位的 PI。 .这需要一段时间。

在开始接收响应时,我将截止时间计时器设置为 800 毫秒(因此传输应该 - 正确地 - 中止)。

这与宣传的一样有效。特别注意socket和timer的取消。请注意,您可以在收到每个数据 block 后再次调用 expires_from_now()。这可能是您想要的。它隐式地cancel()每次计时器还没有过期,所以准备好处理operatorion_aborted消息。

#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/asio/deadline_timer.hpp>

class client
{
public:
client(boost::asio::io_service& io_service,
boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
: deadline_(io_service),
socket_(io_service)
{
boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator,
boost::bind(&client::handle_connect, this,
boost::asio::placeholders::error));
}

void handle_connect(const boost::system::error_code& error)
{
if (!error)
{
std::cout << "Enter message: ";
static char const raw[] = "GET /pi/digits/pi1000000.txt HTTP/1.1\r\nHost: www.angio.net\r\nConnection: close\r\n\r\n";

static_assert(sizeof(raw)<=sizeof(request_), "too large");

size_t request_length = strlen(raw);
std::copy(raw, raw+request_length, request_);

boost::asio::async_write(socket_,
boost::asio::buffer(request_, request_length),
boost::bind(&client::handle_write, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
std::cout << "Handshake failed: " << error.message() << "\n";
}
}

void deadline_expiration(const boost::system::error_code& error)
{
if (error == boost::asio::error::operation_aborted)
return;

std::cout << "\nDEADLINE REACHED\n";
socket_.cancel();
}

void handle_write(const boost::system::error_code& error,
size_t /*bytes_transferred*/)
{
if (!error)
{
std::cout << "starting read loop\n";

deadline_.expires_from_now(boost::posix_time::millisec(800));
//deadline_.expires_from_now(boost::posix_time::seconds(800));
deadline_.async_wait(boost::bind(&client::deadline_expiration, this, boost::asio::placeholders::error));

boost::asio::async_read_until(socket_,
//boost::asio::buffer(reply_, sizeof(reply_)),
reply_, '\n',
boost::bind(&client::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
std::cout << "Write failed: " << error.message() << "\n";
}
}

void handle_read(const boost::system::error_code& error, size_t /*bytes_transferred*/)
{
if (!error)
{
std::cout << "Reply: " << &reply_ << "\n";
boost::asio::async_read_until(socket_,
//boost::asio::buffer(reply_, sizeof(reply_)),
reply_, '\n',
boost::bind(&client::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
std::cout << "Read failed: " << error.message() << "\n";
deadline_.cancel(); // no need for after transfer completed
}
}

private:
boost::asio::deadline_timer deadline_;
boost::asio::ip::tcp::socket socket_;
char request_[1024];
boost::asio::streambuf reply_;
};

int main()
{
try
{
boost::asio::io_service io_service;

boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query("www.angio.net", "80");
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);

client c(io_service, iterator);

io_service.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
}

Coliru link (Coliru 不支持互联网连接)

关于c++ - Boost asio http截止日期错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22594974/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com