From 725667cc47cebd51cbdbdf721ebb179cd6ec48fa Mon Sep 17 00:00:00 2001 From: Titouan Rigoudy Date: Tue, 9 Feb 2016 17:19:51 +0100 Subject: [PATCH] Code basic structure for message handling. Connect to the soulseek server. --- Cargo.lock | 139 +++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 5 ++ src/main.rs | 56 +++++++++++++++++++- src/message.rs | 35 +++++++++++++ src/server.rs | 49 +++++++++++++++++ 5 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 Cargo.lock create mode 100644 src/message.rs create mode 100644 src/server.rs diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..7533ce1 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,139 @@ +[root] +name = "solstice" +version = "0.1.0" +dependencies = [ + "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bytes" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "kernel32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "log" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miow" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "net2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nix" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "slab" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "time" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + diff --git a/Cargo.toml b/Cargo.toml index a181df7..2b2b97e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,3 +2,8 @@ name = "solstice" version = "0.1.0" authors = ["letitz"] + +[dependencies] +mio = "0.5" +log = "0.3.5" +byteorder = "0.4.2" diff --git a/src/main.rs b/src/main.rs index e7a11a9..643f9df 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,57 @@ +mod server; +mod message; + +#[macro_use] extern crate log; +extern crate mio; +extern crate byteorder; + +use mio::{EventLoop, EventSet, Handler, PollOpt, Token}; + +use server::ServerConnection; + +const SERVER_HOST : &'static str = "server.slsknet.org"; +const SERVER_PORT : u16 = 2242; + +const SERVER_TOKEN : Token = Token(0); + +#[derive(Debug)] +struct ConnectionHandler { + server: ServerConnection, +} + +impl ConnectionHandler { + fn new(server: ServerConnection) -> Self { + ConnectionHandler{ server: server } + } +} + +impl Handler for ConnectionHandler { + type Timeout = (); + type Message = (); + + fn ready(&mut self, event_loop: &mut EventLoop, + token: Token, event_set: EventSet) { + + match token { + SERVER_TOKEN => self.server.ready_to_read(), + + _ => unreachable!("Unknown token"), + } + } +} + fn main() { - println!("Hello, world!"); + let server = ServerConnection::new(SERVER_HOST, SERVER_PORT).unwrap(); + + println!("Connected to {:?}", &server); + + let mut event_loop = EventLoop::new().unwrap(); + + event_loop.register( + server.stream(), + SERVER_TOKEN, + EventSet::readable(), + PollOpt::edge()).unwrap(); + + event_loop.run(&mut ConnectionHandler::new(server)).unwrap(); } diff --git a/src/message.rs b/src/message.rs new file mode 100644 index 0000000..c021c71 --- /dev/null +++ b/src/message.rs @@ -0,0 +1,35 @@ +use std::io; +use std::io::Write; + +use byteorder::{LittleEndian, WriteBytesExt}; + +const MAX_MESSAGE_SIZE : usize = 2048; + +pub struct Message { + bytes: Vec, +} + +impl Message { + pub fn new(msg_code: u32) -> Message { + let mut bytes = Vec::with_capacity(MAX_MESSAGE_SIZE); + bytes.write_u32::(msg_code); + Message{ bytes: bytes } + } + + pub fn write_str(&mut self, string: &str) -> io::Result { + try!(self.write_u32::(string.len() as u32)); + let n = try!(self.write(string.as_bytes())); + Ok(n + 4) + } +} + +impl io::Write for Message { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.bytes.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + self.bytes.flush() + } +} + diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..4a54f58 --- /dev/null +++ b/src/server.rs @@ -0,0 +1,49 @@ +use std::io; +use std::net::ToSocketAddrs; + +use mio::tcp::TcpStream; + +use message::Message; + +#[derive(Debug)] +enum ServerState { + NotLoggedIn, + LoggingIn, + LoggedIn, +} + +#[derive(Debug)] +pub struct ServerConnection { + stream: TcpStream, + state: ServerState, +} + +impl ServerConnection { + pub fn new(hostname: &str, port: u16) -> io::Result { + for sock_addr in try!((hostname, port).to_socket_addrs()) { + if let Ok(stream) = TcpStream::connect(&sock_addr) { + return Ok(ServerConnection { + stream: stream, + state: ServerState::NotLoggedIn, + }) + } + } + Err(io::Error::new(io::ErrorKind::Other, + format!("Cannot connect to {}:{}", hostname, port))) + } + + pub fn stream(&self) -> &TcpStream { + &self.stream + } + + pub fn ready_to_read(&mut self) { + match self.state { + _ => () + } + } + + pub fn login(&mut self) { + let msg = Message::new(1); + } +} +