| Crates.io | pea2pea |
| lib.rs | pea2pea |
| version | 0.54.0 |
| created_at | 2020-12-23 07:48:30.712312+00 |
| updated_at | 2025-12-07 10:09:08.11102+00 |
| description | A lightweight, performant microkernel for TCP peer-to-peer (P2P) networking. Handles connection pooling and framing, leaving the logic to you. |
| homepage | https://github.com/ljedrz/pea2pea |
| repository | https://github.com/ljedrz/pea2pea |
| max_upload_size | |
| id | 326425 |
| size | 233,995 |
A clean, modular, and lightweight peer-to-peer networking library for Rust.
pea2pea abstracts away the complex, low-level boilerplate of P2P networking - TCP stream handling, connection pooling, framing, backpressure, etc. - allowing you to focus strictly on your network's logic and protocol implementation.
pea2pea relies strictly on tokio and standard crates, resulting in lightning-fast compile times and tiny binaries.unsafe code involved.Spin up a TCP node capable of receiving messages in 36 lines of code:
use std::{io, net::SocketAddr};
use pea2pea::{Config, ConnectionSide, Node, Pea2Pea, protocols::Reading};
// Define your node
#[derive(Clone)]
struct MyNode {
p2p: Node,
// add your state here
}
// Implement the Pea2Pea trait
impl Pea2Pea for MyNode {
fn node(&self) -> &Node {
&self.p2p
}
}
// Specify how to read network messages
impl Reading for MyNode {
type Message = bytes::BytesMut;
type Codec = tokio_util::codec::LengthDelimitedCodec;
fn codec(&self, _addr: SocketAddr, _side: ConnectionSide) -> Self::Codec {
Default::default()
}
async fn process_message(&self, source: SocketAddr, _message: Self::Message) {
tracing::info!(parent: self.node().span(), "received a message from {source}");
}
}
#[tokio::main]
async fn main() -> io::Result<()> {
// Log events
tracing_subscriber::fmt::init();
// Create the node's configuration
let config = Config {
listener_addr: Some("127.0.0.1:0".parse().unwrap()),
..Default::default()
};
// Instantiate the node
let node = MyNode {
p2p: Node::new(config),
};
// Start reading incoming messages according to the Reading protocol
node.enable_reading().await;
// Start accepting connections
node.p2p.toggle_listener().await?;
// Keep the node running
std::future::pending::<()>().await;
Ok(())
}
pea2pea operates on a modular "hooks" system. You control the connection lifecycle by implementing specific traits, while the library handles the low-level async plumbing.
(For a visual representation, see the Connection Lifecycle Graph)
Simply implement the traits you need:
For full details, refer to the protocols documentation.
pea2pea is built to survive the hostile internet. Its architecture naturally mitigates common denial-of-service vectors without requiring complex configuration:
Reading protocol means that malformed packets or garbage data are rejected at the codec level, instantly dropping the offender before application logic is touched.Challenge: We invite you to try and break a
pea2pea-powered node. Point your favorite stress-testing tool (likehping3or a custom fuzzer) at it; the node will hold its ground.
pea2pea is designed to be as fast as the machine it runs on. To verify the throughput on your specific hardware, run the included benchmark suite:
cargo test --release --test benches -- --nocapture --ignored
Be sure to also check out the stress tests included in the examples.
Check out the examples directory, which is organized by complexity and use case:
Add this to your Cargo.toml:
[dependencies]
pea2pea = "x.x.x" # replace with the latest version
tokio = { version = "1", features = ["rt"] } # pick any other features you need
Current State: Stable & Feature-Complete.
Despite the 0.x versioning, pea2pea is considered production-ready. The core architecture is finished and proven.
Please see CONTRIBUTING.md for details on our strict scope policy.