2 个版本
0.1.1 | 2020 年 8 月 14 日 |
---|---|
0.1.0 | 2020 年 7 月 23 日 |
#3 在 #打洞
9KB
201 行
UDP_HOLE_PUNCHING
这个crate旨在成为rust p2p通信框架。
什么是p2p?
当一个套接字已经“连接”到另一个客户端时,“连接”是直接连接到客户端,而不是服务器。服务器不用于传递数据包,只是将两个客户端配对在一起。正如你所知,这就是UDP 打洞的整个目的。为了实现一个p2p框架,crate提供了2个子函数
- 服务器:如果你想运行一个标准的服务器,等待客户端-被叫发送注册的标识,然后客户端-主叫发送“Ask”命令与客户端-被叫的ID。服务器将每个客户端的IP地址和外部端口号发送给对方。它还有一些基本的防护措施,如防止接收超时等。如果你想更定制化,请查看
make_match
, - 客户端(包括主叫和被叫):在这个crate中,单个UDP传输数据包的大小定义为“pub const Conf.size = 1024;”。然而,crate在发送时会自动拆分超过大小限制的数据,在接收时会自动组装整合,当数据包不完整时请求重发。
快速开始
- main.rs
use async_std::task::block_on;
pub mod server;
pub mod client;
#[macro_use]
extern crate anyhow;
use client::test::*;
use server::process::test_swap_server;
fn main() {
// block_on(test_callee_listen());
// block_on(test_caller_api());
// block_on(test_swap_server());
}
- test_swap_server
pub async fn test_swap_server() {
let host = "x.x.x.x:xxxx";
let res= make_match(host).await;
match res{
Ok(())=>dbg!("everything ok"),
Err(e)=>dbg!(&e.to_string()),
};
}
- test_callee/caller_listen
fn read_file_as_u8(inputfile: &str) -> anyhow::Result<Vec<u8>> {
let mut _inputfile = File::open(inputfile)?;
let mut v: Vec<u8> = Vec::new();
_inputfile.read_to_end(&mut v)?;
Ok(v)
}
fn write_file_as_u8(path_str: &str, binary: &Vec<u8>) -> anyhow::Result<String> {
let p = std::path::Path::new(path_str);
std::fs::write(p, binary)?;
Ok(format!("保存成功,地址:{}", path_str))
}
pub fn test_callee_listen() -> anyhow::Result<()> {
let mut conf = Conf::default();
conf.swap_server = "x.x.x.x:xxxx".to_string();
conf.id = "xx".to_string();
conf.db_path="./data/callee".to_string();
conf.set();
init_udp();
std::thread::spawn(|| {
listen();
});
loop {
std::thread::sleep(Duration::from_secs(10));
let (addr, v) = rec_from();
if &v.len() > &0 {
dbg!("callee rec res");
write_file_as_u8("/home/b.exe", &v)?;
let back = "callee got you".as_bytes().to_vec();
send(&back, addr);
}
};
Ok(())
}
pub fn test_caller_api() -> anyhow::Result<()> {
let mut conf = Conf::default();
conf.swap_server = "x.x.x.x:xxxx".to_string();
conf.db_path="./data/caller".to_string();
conf.set();
init_udp();
std::thread::spawn(|| {
listen();
});
ask_peer_address("xx");
std::thread::sleep(Duration::from_secs(9));
let addr = read_peer_address()?;
dbg!(&addr);
dbg!("begin");
let msg = read_file_as_u8("D://a.exe")?;
let sess=send(&msg, addr);
loop {
let v = rec_one(addr,sess);
if v.len() > 0 {
let s = String::from_utf8_lossy(&v);
dbg!("caller rec res");
}
std::thread::sleep(Duration::from_secs(4));
}
Ok(())
}
谁使用了这个crate?
依赖
~6–16MB
~215K SLoC