Skip to content

Instantly share code, notes, and snippets.

@amedama41
Created October 25, 2015 08:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amedama41/3b3849881fbe093dfaaa to your computer and use it in GitHub Desktop.
Save amedama41/3b3849881fbe093dfaaa to your computer and use it in GitHub Desktop.
Boost.ASIO SSL pending test
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/asio/steady_timer.hpp>
namespace asio = boost::asio;
namespace ssl = asio::ssl;
using tcp = asio::ip::tcp;
auto const endpoint = tcp::endpoint{
asio::ip::address::from_string("127.0.0.1")
, 35555
};
int main(int argc, char const* argv[])
{
asio::io_service io_service{};
asio::spawn(io_service, [&io_service](asio::yield_context yield) {
auto ctx = ssl::context{ssl::context::sslv23};
ctx.set_options(
ssl::context::default_workarounds
| ssl::context::no_sslv2
| ssl::context::single_dh_use);
ctx.use_tmp_dh_file("dh512.pem");
SSL_CTX_set_cipher_list(ctx.native_handle(), "aNULL");
auto acceptor = tcp::acceptor{io_service, endpoint};
ssl::stream<tcp::socket> sock{io_service, ctx};
acceptor.async_accept(sock.next_layer(), yield);
sock.async_handshake(ssl::stream_base::server, yield);
asio::steady_timer timer{io_service, std::chrono::seconds{1}};
timer.async_wait(yield);
sock.async_write_some(asio::buffer("1234567890", 10), yield);
timer.expires_from_now(std::chrono::seconds{1});
timer.async_wait(yield);
sock.async_write_some(asio::buffer("1234567890", 10), yield);
auto ec = boost::system::error_code{};
char buf[256];
while (!ec) {
auto const nread = sock.async_read_some(asio::buffer(buf), yield[ec]);
std::cout << "received ";
std::cout.write(buf, nread) << std::endl;
}
sock.async_shutdown(yield);
});
io_service.poll();
asio::spawn(io_service, [&io_service](asio::yield_context yield) {
auto ctx = ssl::context{ssl::context::sslv23};
SSL_CTX_set_cipher_list(ctx.native_handle(), "aNULL");
ssl::stream<tcp::socket> sock{io_service, ctx};
sock.next_layer().async_connect(endpoint, yield);
sock.async_handshake(ssl::stream_base::client, yield);
char buf1[5];
sock.async_read_some(
asio::buffer(buf1)
, [&](boost::system::error_code, std::size_t nread) {
std::cout << "read result before pending is ";
std::cout.write(buf1, nread) << std::endl;
});
char buf2[15];
auto ec = boost::system::error_code{};
auto const npending = sock.async_read_some(asio::buffer(buf2), yield[ec]);
std::cout
<< "pending read result is expected to \"67890\",\n"
<< "but is \"";
std::cout.write(buf2, npending);
std::cout
<< "\", which length is " << npending << std::endl;
std::cout
<< "And an error occured: " << ec.message() << std::endl;
auto const nread = sock.async_read_some(asio::buffer(buf2), yield);
std::cout << "read result after pending is ";
std::cout.write(buf2, nread) << std::endl;
std::cout << "So, \"67890\" is lost" << std::endl;
sock.async_write_some(
asio::buffer("9876543210", 10)
, [](boost::system::error_code, std::size_t nwrite) {
std::cout << "finish write before peding: " << nwrite << std::endl;
});
std::cout << "start pending write" << std::endl;
auto const nwrite = sock.async_write_some(asio::buffer("0123456789", 10), yield);
std::cout << "finish pending write: " << nwrite << std::endl;
std::cout << "but pending write will be received after shutdown..." << std::endl;
asio::steady_timer timer{io_service, std::chrono::seconds{3}};
timer.async_wait(yield);
std::cout << "shutdown" << std::endl;
sock.async_shutdown(yield);
sock.next_layer().shutdown(tcp::socket::shutdown_send);
});
try {
io_service.run();
}
catch (std::exception const& e) {
std::cout << e.what() << std::endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment