Rust 聊天软件 chat-client

代码来自于【视频】

服务端

use std::io::{ErrorKind, Read, Write};
use std::net::TcpListener;
use std::sync::mpsc;
use std::thread;


const LOCAL:&str = "127.0.0.1:6000";
const MSG_SIZE:usize = 32;


fn sleep(){
    thread::sleep(std::time::Duration::from_millis(100));
}


fn main() {
    let server = TcpListener::bind(LOCAL).expect("Listener failded to bind");
    server.set_nonblocking(true).expect("failed to initialize non-blocking");

    let mut clients = Vec::new();
    let (tx,rx) = mpsc::channel::<String>();
    loop {
        if let Ok((mut socket,addr)) = server.accept(){
            println!("Client {} connected",addr);
            let tx = tx.clone();
            clients.push(socket.try_clone().expect("faild to clone client!"));

            thread::spawn(move || loop {
                let mut buff = vec![0;MSG_SIZE];
                match socket.read_exact(&mut buff){
                    Ok(_) => {
                        let msg = buff.into_iter().take_while(|&x|x!=0).collect::<Vec<_>>();
                        let msg = String::from_utf8(msg).expect("Invalid utf8 msg");

                        println!("{} :{:?}",addr,msg);
                        tx.send(msg).expect("faild to send msg to rx");
                    },
                    Err(ref err) if err.kind() == ErrorKind::WouldBlock => (),
                    Err(_) => {
                        println!("closing connection with : {}",addr);
                        break;
                    }
                }
                sleep();
            });
        };
        if let Ok(msg) = rx.try_recv(){
            clients = clients.into_iter().filter_map(|mut client|{
                let mut buff = msg.clone().into_bytes();
                buff.resize(MSG_SIZE,0);
                client.write_all(&buff).map(|_| client).ok()
            }).collect::<Vec<_>>();
        }
        sleep();
    };
}

客户端

use std::io::{self,ErrorKind, Read, Write};
use std::net::TcpStream;
use std::sync::mpsc::{self,TryRecvError};
use std::thread;
use std::time::Duration;


const LOCAL:&str = "127.0.0.1:6000";
const MSG_SIZE:usize = 32;



fn main() {
    let mut client  = TcpStream::connect(LOCAL).expect("Stream failded to bind");
    client.set_nonblocking(true).expect("failed to initialize non-blocking");

    let (tx,rx) = mpsc::channel::<String>();

    thread::spawn(move || loop {
        let mut buff = vec![0;MSG_SIZE];
        match client.read_exact(&mut buff){
            Ok(_) => {
                let msg = buff.into_iter().take_while(|&x|x!=0).collect::<Vec<_>>();
                println!("msg recv  :{:?}",msg);
            },
            Err(ref err) if err.kind() == ErrorKind::WouldBlock => (),
            Err(_) => {
                println!("connection with server was servered!");
                break;
            }
        };

        match rx.try_recv(){
            Ok(msg) =>{
                let mut buff = msg.clone().into_bytes();
                buff.resize(MSG_SIZE,0);
                client.write_all(&buff).expect("write to socket failed");
                println!("msg send {:?}",msg);
            },
            Err(TryRecvError::Empty)=>(),
            Err(TryRecvError::Disconnected)=>break,
        };
        thread::sleep(Duration::from_millis(100));
    });
    println!("Write a Message:");
    loop{
        let mut buff = String::new();
        io::stdin().read_line(&mut buff).expect("reading from stdin failed");
        let msg = buff.trim().to_string();
        if msg == "quit" || tx.send(msg).is_err(){break};
    };
    println!("byebye!");
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页