• Rust标准库-实现一个TCP服务、Rust使用套接字


    Rust-使用套接字

    Rust 实战 - 使用套接字联网API (一)
    参考URL: https://www.jianshu.com/p/d1048d0b687f
    使用Rust编写一个简单的Socket服务器(1):Rust下的配置载入
    参考URL: https://my.oschina.net/u/4528547/blog/4951186

    rust调libc中的函数

    官网rust可以调的libc:http://www.eclipse.org/paho/files/rustdoc/libc/index.html#
    Rust 实战 - 使用套接字联网API (一)
    参考URL:https://www.jianshu.com/p/d1048d0b687f

    use std::os::raw::c_char;
    use std::ffi::CStr;
    
    extern {
        pub fn gethostname(name: *mut c_char, len: usize) -> i32;
    }
    
    fn main() {
        let len = 255;
        let mut buf = Vec::<u8>::with_capacity(len);
        let ptr = buf.as_mut_ptr() as *mut c_char;
    
        unsafe {
            gethostname(ptr, len);
            println!("{:?}", CStr::from_ptr(ptr));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    extren 表示“外部块(External blocks)”,用来申明外部非 Rust 库中的符号。我们需要使用 Rust 以外的函数,比如 libc ,就需要在 extren 中将需要用到的函数定义出来,然后就可以像使用本地函数一样使用外部函数,编译器会负责帮我们转换。但是,调用一个外部函数是unsafe的,编译器不能提供足够的保证,所以要放到unsafe块中。

    “gethostname” 函数在 C 头文件中的原型是:

    int gethostname(char *name, size_t len);
    
    • 1

    在 Linux 64位平台上,C中的int对应于Rust中的int,size_t对应Rust中的usize,但C中的char与Rust中的char是完全不同的,C中的char始终是i8或者u8,而 Rust 中的char是一个unicode标量值。你也可以去标准库查看。对于指针,Rust 中的裸指针 与C中的指针几乎是一样的,Rust的*mut对应C的普通指针,*const 对应C的const指针。因此我们将类型一一对应,函数的参数名称不要求一致。

    请查看原文!
    Rust 实战 - 使用套接字联网API (一)
    参考URL: https://www.jianshu.com/p/d1048d0b687f

    rust操作套接字API

    官网rust可以调的libc:http://www.eclipse.org/paho/files/rustdoc/libc/index.html#
    Rust 实战 - 使用套接字联网API (一)
    https://www.jianshu.com/p/d1048d0b687f

    说起套接字API,主要包括TCP、UDP、SCTP相关的函数,I/O复用函数和高级I/O函数。其中大部分函数Rust标准里是没有的,如果标准库不能满足你的需求,你可以直接调用libc中的函数。实际上,标准库中,网络这一块,也基本是对libc中相关函数的封装

    请查看原文!
    Rust 实战 - 使用套接字联网API (一)
    参考URL: https://www.jianshu.com/p/d1048d0b687f

    Rust标准库

    标准库:https://doc.rust-lang.org/std/
    标准库net模块:https://doc.rust-lang.org/std/net/index.html

    Rust 标准库是便携式 Rust 软件的基础,它是一组经过实战测试的最小共享抽象,适用于更广泛的 Rust 生态系统。它提供核心类型,如Vec和 Option、库定义的语言原语、标准宏、I/O和 多线程等操作,等等。

    std默认情况下可用于所有 Rust crate。因此,可以use通过路径在语句中 访问标准库std,如use std::env.

    Rust标准库 net

    标准库net模块:https://doc.rust-lang.org/std/net/index.html

    Rust标准库 net模块 提供用于TCP / UDP通信的网络原语。

    该模块为传输控制和用户数据报协议以及 IP 和套接字地址的类型提供网络功能。

    rust实现一个tcp server

    rust实现一个tcp server
    参考URL: https://blog.csdn.net/by186/article/details/117234191
    Rust Web 全栈开发 - 1 构建TCP Server
    参考URL: https://blog.csdn.net/weixin_51487151/article/details/123784175
    【推荐,作者还有压力测试】Rust 编写一个简单,高并发的http服务(纯标准库,编译后168kb),附并发压力测试
    参考URL: https://blog.csdn.net/qq_26373925/article/details/109187251

    服务端

    use std ::net::{TcpListener,TcpStream};
    use std::thread;
    use std::time;
    use std::io;
    use std::io::{Read,Write};
     
     
    fn handle_client(mut stream: TcpStream) -> io::Result<()>{
     
        let mut buf = [0;512];
        for _ in 0..1000{
            let bytes_read = stream.read(&mut buf)?;
            if bytes_read == 0{
                return Ok(());
            }
     
            stream.write(&buf[..bytes_read])?;
            thread::sleep(time::Duration::from_secs(1));
     
        }
        Ok(())
    }
     
    fn main() -> io::Result<()>{
        let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
        let mut thread_vec: Vec<thread::JoinHandle<()>> = Vec::new();
        
        for stream in listener.incoming() {
            let stream = stream.expect("failed");
     
            let handle = thread::spawn(move || {
                handle_client(stream).unwrap_or_else(|error| eprintln!("{:?}",error))
            });
            thread_vec.push(handle);
        }
     
        for handle in thread_vec {
            handle.join().unwrap();
        }
        Ok(())
     
     
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    使用TcpListener监听Socket请求
    使用Read/Write Trait进行Socket数据读写

    客户端

    use std::io::{self,prelude::*,BufReader,Write};
    use std::net::TcpStream;
    use std::str;
     
     
    fn main() -> io::Result<( )> {
        let mut stream = TcpStream::connect("127.0.0.1:7878")?;
        for _ in 0..1000 {
            let mut input = String::new();
            io::stdin().read_line(&mut input).expect("Failed to read");
            stream.write(input.as_bytes()).expect("failed to write");
     
            let mut reader =BufReader::new(&stream);
            let mut buffer: Vec<u8> = Vec::new();
            reader.read_until(b'\n',&mut buffer)?;
            println!("read form server:{}",str::from_utf8(&buffer).unwrap());
            println!("");
     
        }
        Ok(())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    Python堆栈详细介绍
    【深度学习】小结1-入门两周学习感受
    XShell连接VMWare虚拟机
    CTF之变量1
    C++交换a和b的方法
    面试20个人居然没有一个写出数组扁平化?如何手写flat函数
    互斥锁在线程中的使用
    Espresso Test 4: Intent
    gunicorn开启gevent模式,启动服务的时候报超时错误,服务起不来
    C++——stack和queue的使用和OJ练习题
  • 原文地址:https://blog.csdn.net/inthat/article/details/125956576