첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
------------------------------------------------------------------------------------------------------------------------------------------------------
728x90
728x170

■ TCP 프로토콜을 사용해 간이 채팅 프로그램을 만드는 방법을 보여준다.

test_server.zip
0.02MB
test_client.zip
0.02MB

[test_server 프로젝트]

 

▶ src/main.rs

use std::io;
use std::io::BufRead;
use std::io::Write;
use std::net;
use std::sync::mpsc;
use std::thread;
use std::time;

fn main()
{
    let server_address : &str = "127.0.0.1:8888";

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

    let mut tcp_stream_vector : Vec<net::TcpStream> = Vec::new();

    let tcp_listener : net::TcpListener = net::TcpListener::bind(server_address).expect("서버 실행시 에러가 발생했습니다.");

    tcp_listener.set_nonblocking(true).expect("넌블로킹 모드 설정시 에러가 발생했습니다.");

    println!("서버 실행이 시작되었습니다 : {}", server_address);

    loop
    {
        if let Ok((client, client_address)) = tcp_listener.accept()
        {
            println!("클라이언트가 접속했습니다 : {}", client_address);

            tcp_stream_vector.push(client.try_clone().unwrap());

            start_thread(client, tx.clone());
        }

        if let Ok(client_message) = rx.try_recv()
        {
            println!("모든 클라기언트에게 메시지 전송 : {}", client_message.trim());

            tcp_stream_vector = reply_to_all_clients(tcp_stream_vector, &client_message);
        }

        thread::sleep(time::Duration::from_millis(100));
    }
}

fn start_thread(tcp_stream : net::TcpStream, tx : mpsc::Sender<String>)
{
    let mut buf_reader : io::BufReader<net::TcpStream> = io::BufReader::new(tcp_stream);

    thread::spawn
    (
        move ||
        {
            loop
            {
                let mut message : String = String::new();

                if let Ok(byte_count_read) = buf_reader.read_line(&mut message)
                {
                    if byte_count_read > 0
                    {
                        tx.send(message).unwrap();
                    }
                }

                thread::sleep(time::Duration::from_millis(100));
            }
        }
    );
}

fn reply_to_all_clients(tcp_stream_vector : Vec<net::TcpStream>, message : &str) -> Vec<net::TcpStream>
{
    let mut new_tcp_stream_vector : Vec<net::TcpStream> = vec![];

    for mut tcp_stream in tcp_stream_vector.into_iter()
    {
        let message_byte_vector : Vec<u8> = String::from(message).into_bytes();

        if let Err(e) = tcp_stream.write_all(&message_byte_vector)
        {
            println!("전송시 에러가 발생했습니다 : {}", e);

            continue;
        }

        new_tcp_stream_vector.push(tcp_stream);
    }

    return new_tcp_stream_vector;
}

 

[test_client 프로젝트]

 

▶ src/main.rs

use std::io;
use std::io::BufRead;
use std::io::Write;
use std::net;
use std::thread;
use std::time;

fn main()
{
    let server_addresss : &str = "127.0.0.1:8888";

    let mut tcp_stream : net::TcpStream = net::TcpStream::connect(server_addresss).expect("서버 접속시 에러가 발생했습니다.");

    tcp_stream.set_nonblocking(true).expect("넌블로킹 모드 설정시 에러가 발생했습니다.");

    println!("서버에 접속했습니다 : {}", server_addresss);

    start_thread(tcp_stream.try_clone().unwrap());

    let user_name : String = input("사용자명을 입력해 주시기 바랍니다.");

    println!("{}님 메시지를 입력해 주시기 바랍니다.", user_name);

    loop
    {
        let message : String = input("");

        let message : String = format!("{} > {}\n", user_name, message);

        let message_byte_array : &[u8] = message.as_bytes();

        tcp_stream.write_all(message_byte_array).unwrap();
    }
}

fn start_thread(tcp_stream : net::TcpStream)
{
    let mut reader : io::BufReader<net::TcpStream> = io::BufReader::new(tcp_stream);

    thread::spawn
    (
        move ||
        {
            loop
            {
                let mut message : String = String::new();

                if let Ok(byte_count_read) = reader.read_line(&mut message)
                {
                    if byte_count_read > 0
                    {
                        println!("입력 메시지 : {}", message.trim());
                    }
                }

                thread::sleep(time::Duration::from_millis(100));
            }
        }
    );
}

fn input(display_message : &str) -> String
{
    if display_message != ""
    {
        println!("{}", display_message);
    }

    let mut input_message : String = String::new();

    io::stdin().read_line(&mut input_message).expect("메시지 입력시 에러가 발생했습니다.");

    return String::from(input_message.trim());
}
728x90
그리드형(광고전용)
Posted by icodebroker
,