Skip to content

Instantly share code, notes, and snippets.

@tera3939
Created October 28, 2016 03:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tera3939/79bec5405a4dd6d98409d41915250d44 to your computer and use it in GitHub Desktop.
Save tera3939/79bec5405a4dd6d98409d41915250d44 to your computer and use it in GitHub Desktop.
しんどい
[package]
name = "rustcp_server"
version = "0.1.0"
[dependencies]
lazy_static = "0.2.1"
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