I use Tokio to create plain TCP sockets, call tokio::io::split()
and the read/write halves get handed to separate threads. They use the async socket read/write API
It's true that async/await enabled TLS libraries such as tokio-tls require the provided stream to not have been split, however once you have wrapped your stream in a TLS layer, you can split that wrapped stream using tokio::io::split.
Using streams in this way correctly handles all details regarding blocking and non-blocking IO. You do not need to manually configure flags such as O_NONBLOCK
, since Tokio's TcpStream and tokio-tls
's TlsStream handle these details for you behind the scenes.
Using a library that provides blocking sockets would naturally not be compatible with Tokio. This is not new, and is for the same reasons that you can't use std::net::TcpStream within Tokio, as it is a blocking stream. Tokio provides alternate stream types for these purposes to avoid these issues.
If you wanted to use a non-async/await enabled ssl crate, you can perform the crypto on in-memory buffers, and manually write the encrypted data using Tokio's TcpStream
. The async/await enabled ssl libraries all function in this way.