2 个版本

0.1.1 2020 年 8 月 14 日
0.1.0 2020 年 7 月 23 日

#3#打洞


用于 punching_client

MIT 许可证

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