-
-
Save azyobuzin/3d263fea8ba9befec6dd550ce568271f to your computer and use it in GitHub Desktop.
しんどい
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "rustcp_server" | |
version = "0.1.0" | |
[dependencies] | |
lazy_static = "0.2.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::HashMap; | |
use std::io::prelude::*; | |
use std::net::{TcpListener, TcpStream}; | |
use std::sync::{Arc, Mutex, RwLock}; | |
use std::thread; | |
#[macro_use] | |
extern crate lazy_static; | |
lazy_static! { | |
// 各スレッドのTcpStreamをスレッド間で共有する | |
static ref IDS: RwLock<HashMap<String, Arc<Mutex<TcpStream>>>> = { | |
let ids = HashMap::new(); | |
RwLock::new(ids) | |
}; | |
} | |
fn login(stream: Arc<Mutex<TcpStream>>){ | |
/// IDSにUserIDとTcpStreamを保存する | |
let banner = b"Input your UserID: "; | |
let _ = stream.lock().unwrap().write(banner); | |
let mut id = [0;128]; | |
let res = stream.lock().unwrap().read(&mut id); | |
match res { | |
Ok(n) => { | |
let id = std::str::from_utf8(&id[0..n]).unwrap().to_owned(); | |
{ | |
let mut ids = IDS.write().unwrap(); | |
// UserIDとソケットを結びつけ、Thread間で共有する | |
// TcpStreamへの参照はこの関数内で死んでしまうので実体を渡したいけど | |
// cannot move out of borrowed content | |
ids.insert(id, stream); | |
} | |
}, | |
Err(why) => panic!("{:?}", why), | |
} | |
} | |
fn logout(){ | |
/// この関数を呼んだスレッドのTcpStreamをShutdownしてIDSから削除する | |
println!("insert logout"); | |
} | |
fn send_all(message: &str){ | |
/// IDSに格納されたすべてのTcpStreamにmessageをwriteする | |
println!("insert send_all"); | |
} | |
fn handle_client(stream: TcpStream) { | |
/// method CRLF value | |
/// クライアントから送られてきたデータを受信して、methodに対応する関数を呼ぶ | |
let stream = Arc::new(Mutex::new(stream)); | |
loop{ | |
let mut buffer = [0;128]; | |
let res = stream.lock().unwrap().read(&mut buffer); | |
match res { | |
Ok(n) => { | |
if 0 < n { | |
// 受信したデータを&str型に変換 | |
let message = std::str::from_utf8(&buffer[0..n]).unwrap().split("\r\n").next().unwrap(); | |
// \r\nで分割してmethodを取り出す | |
match message { | |
"LOGIN" => login(stream.clone()), | |
"LOGOUT" => logout(), | |
_ => send_all(message), | |
} | |
} | |
}, | |
Err(why) => panic!("{:?}", why), | |
} | |
} | |
} | |
fn main() { | |
// ソケットを生成 | |
let listener = TcpListener::bind("127.0.0.1:8000").unwrap(); | |
println!("Start Listening..."); | |
// accept()してるっぽい | |
for stream in listener.incoming() { | |
println!("Accepted"); | |
match stream { | |
// incoming()がOk返したらhandle_clientのスレッドを生成 | |
Ok(stream) => { | |
thread::spawn(move|| { | |
handle_client(stream) | |
}); | |
} | |
// Errが帰ってきたら頑張る | |
Err(e) => { println!("Error: {:?}", e); } | |
} | |
} | |
// ソケットを閉じる | |
drop(listener); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment