add examples and readme

This commit is contained in:
sijie.sun
2025-01-27 23:04:55 +08:00
parent 9ce5c08807
commit 37f653c74e
4 changed files with 181 additions and 2 deletions
+66
View File
@@ -1,3 +1,69 @@
# kcp-sys
Safe bindings to the [kcp](https://github.com/skywind3000/kcp) transport protocol library.
Also including a high level API for connection state management and data stream handling.
## Usage
1. Create the endpoint and run it.
```rust
let mut endpoint = KcpEndpoint::new();
endpoint.run().await;
```
2. forward the input and output to your transport layer, udp for example.
```rust
let (input, mut output) = (endpoint.input_sender(), endpoint.output_receiver().unwrap());
let udp_socket = Arc::new(UdpSocket::bind("0.0.0.0:54320").await.unwrap());
udp_socket.connect("127.0.0.1:54321").await.unwrap();
let udp = udp_socket.clone();
tokio::spawn(async move {
while let Some(data) = output.recv().await {
udp.send(&data.inner()).await.unwrap();
}
});
let udp = udp_socket.clone();
tokio::spawn(async move {
loop {
let mut buf = vec![0; 1024];
let (size, _) = udp.recv_from(&mut buf).await.unwrap();
input
.send(BytesMut::from(&buf[..size]).into())
.await
.unwrap();
}
});
```
4. Create a connection and send / recv data.
```rust
let conn_id = endpoint
.connect(Duration::from_secs(1), 0, 0, Bytes::new())
.await
.unwrap();
let mut kcp_stream = KcpStream::new(&endpoint, conn_id).unwrap();
kcp_stream.write_all(b"hello world").await.unwrap();
let mut buf = vec![0; 64 * 1024];
let size = kcp_stream.read(&mut buf).await.unwrap();
println!("{}", String::from_utf8_lossy(&buf[..size]));
```
## Tune the kcp parameters
You can tune the kcp parameters by set a config factory to the endpoint.
```rust
let mut endpoint = KcpEndpoint::new();
endpoint.set_kcp_config_factory(|conv| {
KcpConfig::new_turbo(conv)
});
```
+58
View File
@@ -0,0 +1,58 @@
use std::{sync::Arc, time::Duration};
use kcp_sys::{
endpoint::*,
packet_def::{Bytes, BytesMut},
stream::KcpStream,
};
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::UdpSocket,
};
#[tokio::main]
async fn main() {
let mut endpoint = KcpEndpoint::new();
endpoint.run().await;
let (input, mut output) = (endpoint.input_sender(), endpoint.output_receiver().unwrap());
let udp_socket = Arc::new(UdpSocket::bind("0.0.0.0:54320").await.unwrap());
udp_socket.connect("127.0.0.1:54321").await.unwrap();
let udp = udp_socket.clone();
tokio::spawn(async move {
while let Some(data) = output.recv().await {
udp.send(&data.inner()).await.unwrap();
}
});
let udp = udp_socket.clone();
tokio::spawn(async move {
loop {
let mut buf = vec![0; 1024];
let (size, _) = udp.recv_from(&mut buf).await.unwrap();
input
.send(BytesMut::from(&buf[..size]).into())
.await
.unwrap();
}
});
loop {
let conn_id = endpoint
.connect(Duration::from_secs(1), 0, 0, Bytes::new())
.await
.unwrap();
let mut kcp_stream = KcpStream::new(&endpoint, conn_id).unwrap();
kcp_stream.write_all(b"hello world").await.unwrap();
kcp_stream.flush().await.unwrap();
let mut buf = vec![0; 64 * 1024];
let size = kcp_stream.read(&mut buf).await.unwrap();
println!("{}", String::from_utf8_lossy(&buf[..size]));
tokio::time::sleep(Duration::from_secs(1)).await;
}
}
+49
View File
@@ -0,0 +1,49 @@
use std::sync::Arc;
use kcp_sys::{endpoint::*, packet_def::BytesMut, stream::KcpStream};
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::UdpSocket,
};
#[tokio::main]
async fn main() {
let mut endpoint = KcpEndpoint::new();
endpoint.run().await;
let (input, mut output) = (endpoint.input_sender(), endpoint.output_receiver().unwrap());
let udp_socket = Arc::new(UdpSocket::bind("0.0.0.0:54321").await.unwrap());
udp_socket.connect("127.0.0.1:54320").await.unwrap();
let udp = udp_socket.clone();
tokio::spawn(async move {
while let Some(data) = output.recv().await {
udp.send(&data.inner()).await.unwrap();
}
});
let udp = udp_socket.clone();
tokio::spawn(async move {
loop {
let mut buf = vec![0; 1024];
let (size, _) = udp.recv_from(&mut buf).await.unwrap();
input
.send(BytesMut::from(&buf[..size]).into())
.await
.unwrap();
}
});
loop {
let conn_id = endpoint.accept().await.unwrap();
let mut kcp_stream = KcpStream::new(&endpoint, conn_id).unwrap();
let mut buf = vec![0; 64 * 1024];
let size = kcp_stream.read(&mut buf).await.unwrap();
println!("server recv {}", String::from_utf8_lossy(&buf[..size]));
kcp_stream.write_all(&buf[..size]).await.unwrap();
kcp_stream.flush().await.unwrap();
}
}
+8 -2
View File
@@ -1,8 +1,9 @@
use std::fmt::Formatter;
use bytes::{Bytes, BytesMut};
use zerocopy::{AsBytes, FromBytes, FromZeroes, LittleEndian, U32};
pub type BytesMut = bytes::BytesMut;
pub type Bytes = bytes::Bytes;
bitflags::bitflags! {
#[derive(Debug)]
struct KcpPacketHeaderFlags: u8 {
@@ -188,6 +189,7 @@ impl std::fmt::Debug for KcpPacketHeader {
}
}
#[derive(Clone)]
pub struct KcpPacket {
inner: BytesMut,
@@ -256,4 +258,8 @@ impl KcpPacket {
pub fn inner(self) -> BytesMut {
self.inner
}
pub fn len(&self) -> usize {
self.inner.len()
}
}