[asio-users] Sending data over TLS with ASIO (Standalone)
Brought to you by:
chris_kohlhoff
From: Sandra S. <sas...@st...> - 2016-02-02 19:04:31
|
Hello, Currently I'm looking into sending data with ASIO. I understand that io_service is a abstraction of the underlying OS-dependend IO functionality and that the run() call will poll all outstanding handles in the asio queue and finishs afterwards. But looking at the SSL example of asio (see below for my code) I don't know how I can manage to keep the connection (or session) open and read and write data over this connection outside of the normal 'workflow' of the client. That means: if I call my send() method of the client right in handle_handshake the message is send. But if I try to call c.send() from my main method, nothing happens after "Client Handshake success". Why is send() handled different in the descriped scenario? Is io_service already finished? I also tried using asio::io_service::work work(io_service); but the client still does nothing after the handshake. How can I create an simple interface to send data to the server on demand? Many thanks for any help in advance. Best regards, Sandra PS: My code shown below (server and session as in example provided my asio standalone) ------------------------------------------------------------------------------------------- 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; } |