平台Windows
boost中的asio库,并不是编译出来的,而是模板编译的。你在stage/lib/cmake中是找不到的,asio的包的。
asio的ssl支持,使用的是OpenSSL库,因此,需要自己安装OpenSSL库,才能使用。安装OpenSSL之后,仍然需要在项目中引入OpenSSL库,否则会出现头文件、未定义的等等一系列错误。如果你是在windows下,我建议你使用OpenSSL的静态库链接,这样比较简单。下面是代码示例。还有一点,windows的OpenSSL会使用windows的库,所以需要链接#pragma comment(lib, "Crypt32.lib")
cmake_minimum_required(VERSION 3.5)
project(boost-test LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 设置boost搜索路径前缀
set(CMAKE_PREFIX_PATH "D:/library/boost_1_76_0/stage/lib/cmake")
find_package(Boost REQUIRED COMPONENTS json)
add_executable(boost-test main.cpp SslClient.cpp)
# 设置ssl库路径
set(ssl_path "C:/Program Files/OpenSSL-Win64/lib/VC/static/")
# 如果找到boost json库的操作
if (Boost_FOUND)
# 设置头文件,并且链接boost json库以及OpenSSL的静态库
include_directories(${Boost_INCLUDE_DIRS} "C:/Program Files/OpenSSL-Win64/include")
target_link_libraries(${PROJECT_NAME} Boost::json ${ssl_path}libssl64MT.lib ${ssl_path}libcrypto64MT.lib)
endif()
SslClient.h
#ifndef SSLCLIENT_H
#define SSLCLIENT_H
#include <boost/noncopyable.hpp>
#include <boost/json.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <boost/asio/ssl/stream_base.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
class SslClient : public boost::noncopyable
{
public:
using TcpSocketType = boost::asio::ip::tcp::socket;
using SslSocketType = boost::asio::ssl::stream<TcpSocketType>;
explicit SslClient(boost::asio::io_context& io) noexcept;
void start();
void handleRead(const boost::system::error_code& error, std::size_t num) noexcept;
std::string domain;
private:
char _buffer[2048];
boost::asio::io_context& _io;
boost::asio::ssl::context _ctx;
SslSocketType _stream;
};
#endif
SSLClient.cpp
#include "sslclient.h"
#include <iostream>
SslClient::SslClient(boost::asio::io_context& io) noexcept
: _io(io), _ctx(boost::asio::ssl::context::sslv23), _stream(io, _ctx) {}
void SslClient::start() {
boost::asio::ip::tcp::resolver resolver(_io);
boost::asio::ip::tcp::resolver::query query(domain, boost::lexical_cast<std::string>(443));
auto begin = resolver.resolve(query);
boost::asio::ip::tcp::resolver::iterator end;
if (begin == end)
return;
_stream.lowest_layer().connect(begin->endpoint());
_stream.handshake(SslSocketType::handshake_type::client);
const char* strHeader =
"GET / HTTP/1.1\r\n"
"Host: www.baidu.com\r\n"
"Connection: keep-alive\r\n"
"\r\n";
_stream.write_some(boost::asio::const_buffer(strHeader, std::strlen(strHeader)));
_stream.async_read_some(boost::asio::buffer(_buffer, sizeof(_buffer)),
std::bind(&SslClient::handleRead, this,
std::placeholders::_1,
std::placeholders::_2)
);
}
void SslClient::handleRead(const boost::system::error_code& error, std::size_t num) noexcept {
try {
if (error) {
if (num == 0) {
_stream.shutdown();
_stream.lowest_layer().close();
}
return;
}
_buffer[num] = '\0';
std::cout << _buffer;
_stream.async_read_some(boost::asio::buffer(_buffer, sizeof(_buffer)),
std::bind(&SslClient::handleRead, this,
std::placeholders::_1,
std::placeholders::_2)
);
} catch(const std::exception&) {
}
}
main.cpp
#include <iostream>
#include <boost/lexical_cast.hpp>
#include "sslclient.h"
#pragma comment(lib, "Crypt32.lib")
int main(int, char**)
{
std::cout << "hello asio\n";
boost::asio::io_context io;
SslClient app(io);
app.domain = "www.baidu.com";
app.start();
io.run();
}
|