#tcp #tokio #data-stream #byte #data-transfer #io #networking

tcp-handler

Conveniently transfer data in chunk through tokio TCP stream

13 releases (2 stable)

1.0.1 Mar 21, 2024
0.6.0 Mar 20, 2024
0.5.0 Dec 28, 2023

#1032 in Network programming

Download history 62/week @ 2023-12-22 26/week @ 2023-12-29 4/week @ 2024-01-05 6/week @ 2024-01-19 40/week @ 2024-01-26 2/week @ 2024-02-16 3/week @ 2024-02-23 1/week @ 2024-03-01 2/week @ 2024-03-08 300/week @ 2024-03-15 102/week @ 2024-03-22 43/week @ 2024-03-29 91/week @ 2024-04-05

536 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(())
}

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–16MB
~180K SLoC