Crate tcp_handler
source ·Expand description
§Tcp-Handler
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
andWriteHalf
oftokio::net::TcpStream
. (In fact anything implAsyncRead
/AsyncWrite
andUnpin
can be used.) - Support
bytes::Buf
. So you can send discontinuous data chunks by callingchain
. - Support encryption (rsa and aes).
- Support compression (flate2).
- Complete API document and data model.
§Usage
Add this to your Cargo.toml
:
[dependencies]
tcp-handler = "~0.6"
§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
Directly transfer data. Without encryption and compression:
use anyhow::Result;
use bytes::{Buf, BufMut, BytesMut};
use tcp_handler::raw::{client_init, client_start, recv, send, server_init, server_start};
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?;
// Prepare the protocol of tcp-handler.
let client_init = client_init(&mut client, "test", "0.0.0").await;
let server_init = server_init(&mut server, "test", |v| v == "0.0.0").await;
server_start(&mut server, "test", "0.0.0", server_init).await?;
client_start(&mut client, client_init).await?;
// Send.
let mut writer = BytesMut::new().writer();
writer.write_string("hello server.")?;
send(&mut client, &mut writer.into_inner()).await?;
// Receive.
let mut reader = recv(&mut server).await?.reader();
let message = reader.read_string()?;
assert_eq!("hello server.", message);
Ok(())
}
Transfer message with encrypted protocol:
use anyhow::Result;
use bytes::{Buf, BufMut, BytesMut};
use tcp_handler::encrypt::{client_init, client_start, recv, send, server_init, server_start};
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?;
// Prepare the protocol of tcp-handler and the ciphers.
let client_init = client_init(&mut client, "test", "0.0.0").await;
let server_init = server_init(&mut server, "test", |v| v == "0.0.0").await;
let (server_cipher, _protocol_version, _client_version) =
server_start(&mut server, "test", "0.0.0", server_init).await?;
let client_cipher = client_start(&mut client, client_init).await?;
// Send.
let mut writer = BytesMut::new().writer();
writer.write_string("hello server.")?;
send(&mut client, &mut writer.into_inner(), &client_cipher).await?;
// Receive.
let mut reader = recv(&mut server, &server_cipher).await?.reader();
let message = reader.read_string()?;
assert_eq!("hello server.", message);
// Send.
let mut writer = BytesMut::new().writer();
writer.write_string("hello client.")?;
send(&mut client, &mut writer.into_inner(), &server_cipher).await?;
// Receive.
let mut reader = recv(&mut server, &client_cipher).await?.reader();
let message = reader.read_string()?;
assert_eq!("hello client.", message);
Ok(())
}
The transmission method for compressed messages is similar to the above two,
please use methods in compress
and compress_encrypt
mod.
Send discontinuous data chunks:
use anyhow::Result;
use bytes::{Buf, Bytes};
use tcp_handler::raw::{client_init, client_start, recv, send, server_init, server_start};
use tokio::net::{TcpListener, TcpStream};
#[tokio::main]
async fn main() -> Result<()> {
// Connect
let server = TcpListener::bind("localhost:0").await?;
let mut client = TcpStream::connect(server.local_addr()?).await?;
let (mut server, _) = server.accept().await?;
let client_init = client_init(&mut client, "chain", "0").await;
let server_init = server_init(&mut server, "chain", |v| v == "0").await;
server_start(&mut server, "chain", "0", server_init).await?;
client_start(&mut client, client_init).await?;
// Using chain
let mut messages = Bytes::from("a").chain(Bytes::from("b")).chain(Bytes::from("c"));
send(&mut client, &mut messages).await?;
let message = recv(&mut server).await?;
assert_eq!(b"abc", message.as_ref());
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
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Re-exports§
pub extern crate bytes;
Modules§
- Common utilities for this crate.
- compress
compression
Compression protocol. Without encryption. - compress_encrypt
compress_encryption
Compression and encryption protocol. - Global configuration for this crate.
- encrypt
encryption
Encryption protocol. Without compression. - Raw protocol. Without encryption and compression.
Structs§
- When compressing data, the compression level can be specified by a value in this struct.