Rust 網絡編程,實現 TCP 服務端和客戶端程序

本例子用Rust實現一個基於TCP的echo的服務端和客戶端的程序,用Rust演示簡單的網絡程序。

服務端

服務端實現類似於我們之前寫過的http服務端的實現。涉及到的知識點主要是std::io和std::net。代碼如下:

<code>use std::io::{Error, Read, Write};
use std::net::{TcpListener, TcpStream};
use std::thread;
use std::time;

fn handle_client(mut stream: TcpStream) -> 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 as u64));
    }

    Ok(())
}

fn main() -> std::io::Result {
    let listener = TcpListener::bind("127.0.0.1:8080")?;
    let mut thread_vec: Vec> = 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(())
}/<code>

客戶端

在我們以前演示的webserver程序中,我們是使用的瀏覽器來作為客戶端發出請求,本例子中,我們用Rust實現客戶端。源碼如下:

<code>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 = 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(())
}/<code>

知識點總結

在本例子中,我們使用了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()); }
  • BufReaderBufReader每次讀取較多的內容,並且在內存中維護讀取的結果,減少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(()) }


分享到:


相關文章: