14 releases (3 stable)

1.0.2 Jan 5, 2025
1.0.1 Mar 21, 2024
0.6.0 Mar 20, 2024
0.5.0 Dec 28, 2023

#652 in Network programming

Download history 26/week @ 2024-09-22 8/week @ 2024-09-29 34/week @ 2024-12-08 2/week @ 2024-12-15 121/week @ 2025-01-05

123 downloads per month
Used in 2 crates

MIT/Apache

110KB
1K SLoC

Tcp-Handler

Crate GitHub last commit GitHub issues GitHub pull requests GitHub

Read this in other languages: English, 简体中文.

Description

More conveniently use tokio::net::TcpStream to transfer bytes::Bytes data chunks.

You may use extra crate to read and write data, such as serde, postcard and variable-len-reader.

See tcp-server and tcp-client for conveniently building your tcp application.

Features

  • Based on tokio and bytes.
  • Support ReadHalf and WriteHalf of tokio::net::TcpStream. (In fact anything impl AsyncRead/AsyncWrite and Unpin can be used.)
  • Support bytes::Buf. So you can send discontinuous data chunks by calling chain.
  • Support encryption (rsa and aes).
  • Support compression (flate2).
  • Complete API document and data model.

Usage

Add this to your Cargo.toml:

[dependencies]
tcp-handler = "^1.0"

Note

If client_init using encryption mode is extremely slow in debug mode, please add this to your Cargo.toml in client side:

[profile.dev.package.num-bigint-dig]
opt-level = 3 # Speed up rsa key gen.

This is an issue in rsa crate.

Example

With TcpHandler, you can use all the protocols in a similar way.

use anyhow::{Error, Result};
use bytes::{Buf, BufMut, BytesMut};
use tcp_handler::raw::*;
use tokio::{spawn, try_join};
use tokio::net::{TcpListener, TcpStream};
use variable_len_reader::{VariableReader, VariableWriter};

#[tokio::main]
async fn main() -> Result<()> {
    // Create tcp stream.
    let server = TcpListener::bind("localhost:0").await?;
    let mut client = TcpStream::connect(server.local_addr()?).await?;
    let (mut server, _) = server.accept().await?;
    
    let client = spawn(async move {
        let mut client = TcpClientHandlerRaw::from_stream(client, "YourApplication", "1.0.0").await?;

        // Send.
        let mut writer = BytesMut::new().writer();
        writer.write_string("hello server.")?;
        client.send(&mut writer.into_inner()).await?;
      
        Ok::<_, Error>(())
    });
    let server = spawn(async move {
        let mut server = TcpServerHandlerRaw::from_stream(server, "YourApplication", |v| v == "1.0.0", "1.0.0").await?;
        assert_eq!(server.get_client_version(), "1.0.0");

        // Receive.
        let mut reader = server.recv().await?.reader();
        let res = reader.read_string()?;
        assert_eq!(res, "hello server.");

        Ok::<_, Error>(())
    });
    try_join!(client, server)?;
    Ok(())
}

Benchmarks

Speed: raw > compress > compress_encrypt > encrypt

But currently the benchmarks are not serious. Welcome to contribute.

Protocol Version

The protocol version code used internally. Note only when the server and client sides have the same code, they can connect normally.

crate version protocol version
>=0.6.0 1
<0.6.0 0

License

Licensed under either of

at your option.

Dependencies

~3–12MB
~129K SLoC