Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 不允许我删除ssl::stream<;tcp::socket>;是否有未决操作?_C++_Sockets_Ssl_Boost - Fatal编程技术网

C++ 不允许我删除ssl::stream<;tcp::socket>;是否有未决操作?

C++ 不允许我删除ssl::stream<;tcp::socket>;是否有未决操作?,c++,sockets,ssl,boost,C++,Sockets,Ssl,Boost,我有一个boost::asio::ssl::stream事实上,你不是: 不同对象:安全 共享对象:不安全。应用程序还必须确保所有异步操作都在同一隐式或显式串中执行 通常的方法是将会话(“连接”)设为boost::从\u this派生类启用\u shared\u,并将完成处理程序绑定到shared\u from\u this()。这样,您就可以让shared_ptr超出范围,并且只有在最后一个挂起的操作(包括完成处理程序)完成后,对象才会被删除 奖金 这是等效的代码,没有“假”异步,具有自动

我有一个
boost::asio::ssl::stream事实上,你不是:

不同对象:安全

共享对象:不安全。应用程序还必须确保所有异步操作都在同一隐式或显式串中执行


通常的方法是将会话(“连接”)设为
boost::从\u this
派生类启用\u shared\u,并将完成处理程序绑定到
shared\u from\u this()
。这样,您就可以让
shared_ptr
超出范围,并且只有在最后一个挂起的操作(包括完成处理程序)完成后,对象才会被删除

奖金

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

#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";
}
#包括
#包括
#包括
名称空间ba=boost::asio;
名称空间ssl=ba::ssl;
使用ba::ip::tcp;
int main()
{
字符缓冲区[4096];
const char*write=“GET/HTTP/1.1\r\n主机:127.0.0.1\r\n\r\n”;
ba::io_服务io;
ssl::context ssl_context(ssl::context::tlsv1);
ssl::流套接字(io、ssl\U上下文);
socket.set_verify_模式(ssl::verify_none);
tcp::解析器(io);
解析程序::查询查询(“stackoverflow.com”,std::to_string(443));
自动结果=解析程序。解析(查询);
socket.next_layer().connect(*结果);
握手(ssl::stream\u base::client);
/*size\u 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);
国际单项体育联合会(欧共体){
std::cout事实上,你不是:

不同对象:安全

共享对象:不安全。应用程序还必须确保在同一隐式或显式链中执行所有异步操作


通常的方法是将会话(“连接”)设置为
boost::从\u this
派生类启用\u shared\u,并将完成处理程序绑定到
shared\u from\u this()
。这样,您就可以让
shared\u ptr
超出范围,并且只有在最后一个挂起的操作完成后才会删除该对象(包括完成处理人)

奖金

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

#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";
}
#包括
#包括
#包括
名称空间ba=boost::asio;
名称空间ssl=ba::ssl;
使用ba::ip::tcp;
int main()
{
字符缓冲区[4096];
const char*write=“GET/HTTP/1.1\r\n主机:127.0.0.1\r\n\r\n”;
ba::io_服务io;
ssl::context ssl_context(ssl::context::tlsv1);
ssl::流套接字(io、ssl\U上下文);
socket.set_verify_模式(ssl::verify_none);
tcp::解析器(io);
解析程序::查询查询(“stackoverflow.com”,std::to_string(443));
自动结果=解析程序。解析(查询);
socket.next_layer().connect(*结果);
握手(ssl::stream\u base::client);
/*size\u 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);
国际单项体育联合会(欧共体){

std::难道这很有趣吗。那里的代码编写方式似乎没有任何异步。你可以一直使用同步调用。为什么
socket
甚至在这里是动态分配的?@sehe这是一个用于暴露我的问题的最小代码。好吧,很公平。它简化了很多,让事情复杂化的原因已经不存在了。@sehe更清楚一点。粘贴的代码会因segfault而崩溃。这很有趣。那里的代码编写方式似乎没有任何异步。你可以一直使用同步调用。为什么
socket
甚至在这里是动态分配的?@sehe这是一个用于暴露我的问题的最小代码。好吧,很公平。它只是简化了很多,th在这里,使内容复杂化的原因已经不存在了。@sehe只是为了让它更清楚。粘贴的代码将因segfault而崩溃。添加了等效代码,简化了很多。您能帮我解释引用的文本吗?我不明白这如何意味着如果存在挂起的异步操作,则不允许销毁。实际上,从技术上讲,你是对的。我确实假设你的真实代码没有那么做作,并且涉及真正的异步。是的,运行析构函数原则上只会取消任何挂起的操作。但是运行析构函数不同步会导致未定义的行为。当然,你的原始示例没有显示任何这种情况。你建议使用共享\u ptrs(和cancel(),而不是删除套接字)解决了我的问题。但是,我会继续研究,因为我仍然不确定这是否是一个bug。添加了等效代码,简化了很多。你能帮我解释引用的文本吗?我不明白这意味着如果有未决的异步操作,销毁是不允许的。嗯。从技术上说,你是对的。我做了ume您的实际代码没有那么做作,并且涉及真正的异步。是的,运行析构函数原则上只会取消任何挂起的操作。但是运行析构函数不同步会导致未定义的行为。当然,您的原始示例没有显示任何这种情况。您建议使用共享的\u ptr(和cancel()而不是删除套接字)解决了我的问题。然而,我会继续研究,因为我仍然不确定这是否是一个错误。