Created
October 28, 2016 03:56
-
-
Save tera3939/79bec5405a4dd6d98409d41915250d44 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::RwLock; | |
use std::thread; | |
#[macro_use] | |
extern crate lazy_static; | |
lazy_static! { | |
// 各スレッドのTcpStreamをスレッド間で共有する | |
static ref IDS: RwLock<HashMap<&'static str, TcpStream>> = { | |
let ids = HashMap::new(); | |
RwLock::new(ids) | |
}; | |
} | |
fn login(stream: &mut TcpStream){ | |
/// IDSにUserIDとTcpStreamを保存する | |
let banner = b"Input your UserID: "; | |
let _ = stream.write(banner); | |
let mut id = [0;128]; | |
match stream.read(&mut id) { | |
Ok(n) => { | |
let id = std::str::from_utf8(&id[0..n]).unwrap(); | |
{ | |
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(mut stream: TcpStream) { | |
/// method CRLF value | |
/// クライアントから送られてきたデータを受信して、methodに対応する関数を呼ぶ | |
loop{ | |
let mut buffer = [0;128]; | |
match stream.read(&mut buffer) { | |
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(&mut stream), | |
"LOGOUT" => logout(), | |
_ => send_all(message), | |
} | |
} | |
}, | |
Err(why) => panic!("{:?}", why), | |
} | |
} | |
} | |
fn main() { | |
// ソケットを生成 | |
let listener = TcpListener::bind("127.0.0.1:8000").unwrap(); | |
println!("Start Listenig..."); | |
// accept()してるっぽい | |
for stream in listener.incoming() { | |
println!("Accepted"); | |
match stream { | |
// incoming()がOk返したらhandle_clientのスレッドを生成 | |
Ok(stream) => { | |
let mut stream = 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