gpt4 book ai didi

c++ - 如果 ssl::stream 有未决操作,我是否不允许删除它?

转载 作者:行者123 更新时间:2023-11-30 01:47:01 25 4
gpt4 key购买 nike

我有一个 boost::asio::ssl::stream<boost::asio::ip::tcp::socket握手已经完成。我开始异步读取,然后删除该对象(我销毁它并将其内存重置为 0xff)。然后,我得到一个段错误,因为 Boost Asio 正在访问我刚刚删除的对象中的内容。当我只用 boost::asio::ip::tcp::socket 测试它时我的回调只是在操作中止时被调用,这是我在使用 ssl::stream 时所期望的。

我用来重现问题的代码:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>

template <typename T>
void debug(T& a)
{
for (unsigned int i = 0; i < sizeof(a); ++i)
{
if (i % 8 == 0) std::cout << std::endl << i << "\t";
std::cout << unsigned(reinterpret_cast<unsigned char*>(&a)[i]) << " ";
}
std::cout << std::endl;
}

template <typename T>
void destruct(T& a)
{
a.~T();
memset(&a, 0xff, sizeof(a));
}

int main()
{
char buffer[4096];
const char* write = "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n";

boost::asio::io_service io;
//boost::asio::ip::tcp::socket* socket = new boost::asio::ip::tcp::socket(io);
boost::asio::ssl::context ssl_context(boost::asio::ssl::context::tlsv1);

boost::asio::ssl::stream<boost::asio::ip::tcp::socket>* socket = new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(io, ssl_context);
socket->set_verify_mode(boost::asio::ssl::verify_none);

boost::asio::ip::tcp::resolver resolver(io);
boost::asio::ip::tcp::resolver::query query("stackoverflow.com", std::to_string(443));

resolver.async_resolve(query, [&](const boost::system::error_code& ec, boost::asio::ip::tcp::resolver::iterator result)
{
if (ec) throw ec;

//socket->async_connect(*result, [&](const boost::system::error_code& ec)
socket->next_layer().async_connect(*result, [&](const boost::system::error_code& ec)
{
if (ec) throw ec;

socket->async_handshake(boost::asio::ssl::stream_base::client, [&](const boost::system::error_code& ec)
{
if (ec) throw ec;

boost::asio::async_write(*socket, boost::asio::buffer(write, std::string(write).size()), [&](const boost::system::error_code& ec, std::size_t)
{
if (ec) throw ec;


socket->async_read_some(boost::asio::buffer(buffer, 4096), [&](const boost::system::error_code& ec, std::size_t len)
{
if (ec) {
std::cout << ec.message() << std::endl;
debug(*socket);
return;
}

std::cout.write(buffer, len);

std::cout << std::endl << "End" << std::endl;
});

debug(*socket);
destruct(*socket);
});

}
);
});
});

io.run();

debug(*socket);
}

最佳答案

事实上你不是:

Thread Safety

Distinct objects: Safe.

Shared objects: Unsafe. The application must also ensure that all asynchronous operations are performed within the same implicit or explicit strand.


通常的方法是使您的 session (“连接”)成为 boost::enable_shared_from_this派生类并将完成处理程序绑定(bind)到 shared_from_this() .这样,您就可以让 shared_ptr<Session>超出范围,只有在最后一个挂起的操作完成(包括完成处理程序)后,该对象才会被删除。

奖金

这是等效的代码,没有“假”异步,具有自动生命周期和隐式异常!

Live On Coliru

#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>

namespace ba = boost::asio;
namespace ssl = ba::ssl;
using ba::ip::tcp;

int main()
{
char buffer[4096];
const char* write = "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n";

ba::io_service io;
ssl::context ssl_context(ssl::context::tlsv1);
ssl::stream<tcp::socket> socket(io, ssl_context);

socket.set_verify_mode(ssl::verify_none);

tcp::resolver resolver(io);
tcp::resolver::query query("stackoverflow.com", std::to_string(443));

auto result = resolver.resolve(query);
socket.next_layer().connect(*result);

socket.handshake(ssl::stream_base::client);

/*size_t ignore = */ba::write(socket, ba::buffer(write, std::string(write).size()));

boost::system::error_code ec;
size_t len = socket.read_some(ba::buffer(buffer, 4096), ec);
if (ec) {
std::cout << ec.message() << "\n";
} else {
std::cout.write(buffer, len);
}

std::cout << "\nEnd\n";
}

关于c++ - 如果 ssl::stream<tcp::socket> 有未决操作,我是否不允许删除它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32260702/

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