C++ 使用Boost:ASIO和ASIO SSL示例代码通过TLS发送数据
目前我正在研究使用Boost ASIO发送数据。我知道C++ 使用Boost:ASIO和ASIO SSL示例代码通过TLS发送数据,c++,boost,boost-asio,C++,Boost,Boost Asio,目前我正在研究使用Boost ASIO发送数据。我知道io\u服务是底层依赖操作系统的io功能的抽象,调用run()将轮询asio队列中所有未完成的句柄,并在之后完成 但是看看asio的SSL示例(代码见下文),我不知道如何在客户端的正常“工作流程”之外保持连接(或会话,或其他)打开并通过此连接读写数据 这意味着:如果我在handle\u handshake中调用客户端的send()方法,消息就被发送了。但是,如果我尝试从主方法调用c.send(),则在客户端握手成功后,什么也不会发生 为什么在
io\u服务
是底层依赖操作系统的io功能的抽象,调用run()
将轮询asio队列中所有未完成的句柄,并在之后完成
但是看看asio的SSL示例(代码见下文),我不知道如何在客户端的正常“工作流程”之外保持连接(或会话,或其他)打开并通过此连接读写数据
这意味着:如果我在handle\u handshake
中调用客户端的send()
方法,消息就被发送了。但是,如果我尝试从主方法调用c.send()
,则在客户端握手成功后,什么也不会发生
为什么在所描述的场景中处理的send()
不同?io\u服务是否已完成
注意:请不要担心下面的代码量。这是ASIO standalone提供的示例代码。在一个运行的示例中,我只向客户机添加了一个自定义send()方法,并添加了一个main来执行客户机和服务器
编辑
我还尝试使用asio::io_服务::工作(io_服务)
但是客户端在握手后仍然什么也不做
class session{
public:
session(asio::io_service& io_service,
asio::ssl::context& context)
: socket_(io_service, context) { }
ssl_socket::lowest_layer_type& socket(){
return socket_.lowest_layer();
}
void start(){
std::cout << " Session start "<< "\n";
socket_.async_handshake(asio::ssl::stream_base::server,
std::bind(&session::handle_handshake, this,
std::placeholders::_1));
}
void handle_handshake(const asio::error_code& error){
if (!error){
std::cout << " Session handshake success "<< "\n";
socket_.async_read_some(asio::buffer(data_, max_length),
std::bind(&session::handle_read, this,
std::placeholders::_1, std::placeholders::_2));
}
else {
std::cout << " Session handshake failed "<< "\n";
delete this;
}
}
void handle_read(const asio::error_code& error,
size_t bytes_transferred) {
if (!error) {
std::cout << " Session Read success "<< "\n";
asio::async_write(socket_,
asio::buffer(data_, bytes_transferred),
std::bind(&session::handle_write, this,
std::placeholders::_1));
}
else {
std::cout << " Session Read failed "<< "\n";
delete this;
}
}
void handle_write(const asio::error_code& error){
if (!error){
std::cout << " Write success "<< "\n";
socket_.async_read_some(asio::buffer(data_, max_length),
std::bind(&session::handle_read, this,
std::placeholders::_1,
std::placeholders::_2));
}
else{
delete this;
}
}
private:
ssl_socket socket_;
enum { max_length = 1024 };
char data_[max_length];
};
class server
{
public:
server(asio::io_service& io_service, unsigned short port)
: io_service_(io_service),
acceptor_(io_service,
asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port)),
context_(asio::ssl::context::sslv23) {
context_.set_options(
asio::ssl::context::default_workarounds
| asio::ssl::context::no_sslv2
| asio::ssl::context::single_dh_use);
context_.set_password_callback(std::bind(&server::get_password, this));
context_.use_certificate_chain_file("server.pem");
context_.use_private_key_file("server.pem", asio::ssl::context::pem);
context_.use_tmp_dh_file("dh1024.pem");
start_accept();
}
std::string get_password() const{
return "test";
}
void start_accept(){
std::cout << " Server accept start "<< "\n";
session* new_session = new session(io_service_, context_);
acceptor_.async_accept(new_session->socket(),
std::bind(&server::handle_accept, this, new_session,
std::placeholders::_1));
}
void handle_accept(session* new_session,
const asio::error_code& error){
if (!error){
std::cout << " Server Accept success "<< "\n";
new_session->start();
}
else
{
delete new_session;
}
start_accept();
}
private:
asio::io_service& io_service_;
asio::ip::tcp::acceptor acceptor_;
asio::ssl::context context_;
};
enum { max_length = 1024 };
class client
{
public:
client(asio::io_service& io_service,
asio::ssl::context& context,
asio::ip::tcp::resolver::iterator endpoint_iterator)
: socket_(io_service, context) {
socket_.set_verify_mode(asio::ssl::verify_peer);
socket_.set_verify_callback(
std::bind(&client::verify_certificate, this, std::placeholders::_1, std::placeholders::_2));
asio::async_connect(socket_.lowest_layer(), endpoint_iterator,
std::bind(&client::handle_connect, this,
std::placeholders::_1));
}
bool verify_certificate(bool preverified,
asio::ssl::verify_context& ctx){
return true;
}
void handle_connect(const asio::error_code& error){
if (!error){
std::cout << "Client Connect success "<< "\n";
socket_.async_handshake(asio::ssl::stream_base::client,
std::bind(&client::handle_handshake, this,
std::placeholders::_1));
}
else {
std::cout << "Client Connect failed: " << error.message() << "\n";
}
}
void handle_handshake(const asio::error_code& error){
if (!error) {
std::cout << "Client Handshake success "<< "\n";
//send("test") no send here
}
else{
std::cout << "Client Handshake failed: " << error.message() << "\n";
}
}
void send(char * request_){
std::cout << " Client Sende daten "<< "\n";
size_t request_length = strlen(request_);
asio::async_write(socket_,
asio::buffer(request_, request_length),
std::bind(&client::handle_write, this,
std::placeholders::_1,
std::placeholders::_2));
}
void handle_write(const asio::error_code& error, size_t bytes_transferred){
if (!error)
{
std::cout << " Client Write success "<< "\n";
asio::async_read(socket_,
asio::buffer(reply_, bytes_transferred),
std::bind(&client::handle_read, this,
std::placeholders::_1,
std::placeholders::_2));
}
else {
std::cout << "Client Write failed: " << error.message() << "\n";
}
}
void handle_read(const asio::error_code& error, size_t bytes_transferred) {
if (!error) {
std::cout << "Client Reply: ";
std::cout.write(reply_, bytes_transferred);
std::cout << "\n";
}
else {
std::cout << "Client Read failed: " << error.message() << "\n";
}
}
private:
asio::ssl::stream<asio::ip::tcp::socket> socket_;
char request_[max_length];
char reply_[max_length];
};
using namespace std;
int main(){
std::thread t {
[](){
asio::io_service server_service;
server s(server_service, 8877);
server_service.run();
}
};
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
asio::io_service io_service;
asio::ip::tcp::resolver resolver(io_service);
asio::ip::tcp::resolver::query query("127.0.0.1", std::to_string(8877));
asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
asio::ssl::context ctx(asio::ssl::context::sslv23);
ctx.load_verify_file("ca.pem");
client c(io_service, ctx, iterator);
c.send("test");
io_service.run();
t.join();
return 0;
}
课堂会话{
公众:
会话(asio::io_服务和io_服务,
asio::ssl::上下文和上下文)
:套接字(io_服务,上下文){}
ssl_套接字::最低层_层_类型和套接字(){
返回套接字。最低层();
}
void start(){
标准::cout