美文网首页RUST编程
001 Rust 网络编程,实现 TCP 服务端和客户端程序

001 Rust 网络编程,实现 TCP 服务端和客户端程序

作者: 令狐壹冲 | 来源:发表于2020-04-25 20:21 被阅读0次

    本例子用Rust实现一个基于TCP的echo的服务端和客户端的程序,用Rust演示简单的网络程序。

    服务端

    服务端实现类似于我们之前写过的http服务端的实现。涉及到的知识点主要是std::io和std::net。
    代码如下:

    use std::io::{Error, Read, Write};
    use std::net::{TcpListener, TcpStream};
    use std::thread;
    use std::time;
    
    fn handle_client(mut stream: TcpStream) -> Result<(), Error>{
        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 as u64));
        }
    
        Ok(())
    }
    
    fn main() -> std::io::Result<()> {
        let listener = TcpListener::bind("127.0.0.1:8080")?;
        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(())
    }
    

    客户端

    在我们以前演示的webserver程序中,我们是使用的浏览器来作为客户端发出请求,本例子中,我们用Rust实现客户端。
    源码如下:

    use std::io::{self, prelude::*, BufReader, Write};
    use std::net::TcpStream;
    use std::str;
    
    fn main() -> std::io::Result<()> {
        let mut stream = TcpStream::connect("127.0.0.1:8080")?;
        for _ in 0..10 {
            let mut input = String::new();
            io::stdin()
                .read_line(&mut input)
                .expect("Failed to read from stdin");
            stream
                .write(input.as_bytes())
                .expect("Failed to write to stream");
            
            let mut reader = BufReader::new(&stream);
            let mut buffer: Vec<u8> = Vec::new();
            reader
                .read_until(b'\n', &mut buffer)
                .expect("Could not read into buffer");
            println!("{}", 
                str::from_utf8(&buffer).expect("Could not write buffer as string"));
            println!("");
        }
        Ok(())
    }
    

    知识点总结

    在本例子中,我们使用了io库读取一些内容。

    • 从标准输入读取
      BufRead是一种类型的Reader,它具有一个内部缓冲区,允许它执行其它读取方式。
      例如,在不使用缓冲区的情况下,逐行读取效率低下,因此,如果要逐行读取,则需要BufRead,它包括read_line方法和行迭代器。
      标准输入实现了BufRead,例子如下:
    use std::io;
    use std::io::prelude::*;
    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        println!("{}", line.unwrap());
    }
    
    • BufReader
      BufReader每次读取较多的内容,并且在内存中维护读取的结果,减少Read系统调用的次数,提高效率。
      BufReader使用例子:
    use std::io::prelude::*;
    use std::io::BufReader;
    use std::fs::File;
    fn main() -> std::io::Result<()> {
        let f = File::open("log.txt")?;
        let mut reader = BufReader::new(f);
    
        let mut line = String::new();
        let len = reader.read_line(&mut line)?;
        println!("First line is {} bytes long", len);
        Ok(())
    }
    

    相关文章

      网友评论

        本文标题:001 Rust 网络编程,实现 TCP 服务端和客户端程序

        本文链接:https://www.haomeiwen.com/subject/ciqlwhtx.html