繁体   English   中英

提升asio SSL stream.shutdown(ec); 总是有错误,这是boost :: asio :: ssl :: error :: stream_truncated

[英]boost asio SSL stream.shutdown(ec); always had error which is boost::asio::ssl::error::stream_truncated

我尝试使用Boost Asio和Openssl将一些json发布到SSL服务器,我的情况是它总是有问题,当我尝试关闭流时,存在boost :: asio :: ssl :: error :: stream_truncated问题,现在我试图忽略该问题,我不知道该忽略还是做错了什么? Boost版本为1.68.0,Openssl版本1.1.1,VS 2017 CE,Windows 7 x64,

这是我的代码

#include "root_certificates.hpp"
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/error.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <cstdlib>
#include <iostream>
#include <string>
#include <time.h>
#include<fstream>
#include <ctime>
#include <istream>

   int postsslserver()
  {
     try
     {
       auto const host ="mydomain.com";
        auto const port = "https";
        auto const target ="/apps/postpage.html" ;
        retcode = 0;



        setlocale(LC_ALL, "");

        pwmd5hashed = "mysecret";

        std::string jsondata ="\"Double\":12.0000001,";

        int version =11;

         // The io_context is required for all I/O
        boost::asio::io_context ioc;

        // The SSL context is required, and holds certificates
        ssl::context ctx{ ssl::context::sslv23_client };

         //20181021
        ctx.set_default_verify_paths();

        // This holds the root certificate used for verification
        //load_root_certificates(ctx);

         // Verify the remote server's certificate
        //ctx.set_verify_mode(ssl::verify_peer);
        ctx.set_verify_mode(ssl::verify_none);

        // These objects perform our I/O
        tcp::resolver resolver{ ioc };
        ssl::stream<tcp::socket> stream{ ioc, ctx };

       // Set SNI Hostname (many hosts need this to handshake successfully)
       if (!SSL_set_tlsext_host_name(stream.native_handle(), host))
       {
            boost::system::error_code ec{ static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category() };
             throw boost::system::system_error{ ec };
        }

        // Look up the domain name
        auto const results = resolver.resolve(host, port);

        // Make the connection on the IP address we get from a lookup
        boost::asio::connect(stream.next_layer(), results.begin(), results.end());

        // Perform the SSL handshake
        stream.handshake(ssl::stream_base::client);// error always occured this line of code,the error hints was "handshake: certificate verify failed"

         // Set up an HTTP POST request message
        http::request<http::string_body> req{ http::verb::post, target, version };
        req.set(http::field::host, host);
        req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
        req.set(http::field::content_type, "application/json");
        req.set(http::field::body, jsondata);

        // Send the HTTP request to the remote host
        http::write(stream, req);

        // This buffer is used for reading and must be persisted
        boost::beast::flat_buffer buffer;

         // Declare a container to hold the response
         http::response<http::dynamic_body> res;

         // Receive the HTTP response
          http::read(stream, buffer, res);

       // Write the message to standard out
       std::cout << res << std::endl;

       // Gracefully close the stream
        boost::system::error_code ec;
        stream.shutdown(ec);// the problem was here! it always get boost::asio::ssl::error::stream_truncated issue
        if (ec == boost::asio::error::eof)
       {
        // Rationale:

            ec.assign(0, ec.category());
        }
         if (ec!= boost::asio::ssl::error::stream_truncated)//then I tried to ignore it
         {
              std::cout << ec.message()<< endl;
              throw boost::system::system_error{ ec };
          }

        // If we get here then the connection is closed gracefully
    }
   catch (std::exception const& e)
   {
    //std::cerr << "Error: " << e.what() << std::endl;
        write_text_to_log_file(e.what());
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

非常感谢你

安全关闭SSL套接字的正确方法不是直接尝试shutdown它。

首先,您必须cancel所有可能的未完成操作,然后启动shutdown并随后close套接字。

这是一个可行的解决方案的片段:

virtual void OnClose(boost::system::error_code &ec)
{
    //...
    _socket.lowest_layer().cancel(ec);
    _socket.async_shutdown(std::bind(&Socket<T>::ShutdownHandler, this->shared_from_this(), std::placeholders::_1));
    //...
}

void ShutdownHandler(const boost::system::error_code &ec)
{
    //On async_shutdown both parties send and receive a 'close_notify' message.
    //When the shutdown has been negotiated by both parties, the underlying
    //transport may either be reused or closed.
    //The initiator of the shutdown will enter the shutdown-handler with an
    //error value of eof. (Socket was securely shutdown)
    if (ec && ec != boost::asio::error::eof)
    {
        LogError(ec, Error::ErrorLocation(__FUNCTION__, __LINE__));
    }

    boost::system::error_code ec2;
    _socket.lowest_layer().close(ec2);
    if (ec2)
        LogError(ec2, Error::ErrorLocation(__FUNCTION__, __LINE__));
    _shutdownComplete.exchange(true);
}

另外: boost asio ssl async_shutdown总是以错误结束吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM