Browse Source

Created IPInterface constructor. Made nonblocking mainloop in IP

interface-2
Prokhor 3 years ago
parent
commit
50ecec2aa3
  1. 47
      examples/test_ip_connection.rs
  2. 165
      src/interfaces/ip.rs
  3. 2
      src/lib.rs

47
examples/test_ip_connection.rs

@ -4,53 +4,44 @@ use ironforce::interface::Interface;
use ironforce::interfaces::ip::IPInterface; use ironforce::interfaces::ip::IPInterface;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::net; use std::net;
use std::thread;
use std::time::Duration;
#[cfg(feature = "std")]
use ironforce::res::IFResult;
#[cfg(feature = "std")] #[cfg(feature = "std")]
fn main() { fn main() {
let mut listener = match net::TcpListener::bind("0.0.0.0:60000") { println!("hello");
Ok(tmp) => tmp, test();
Err(_) => { }
return;
}
};
let mut interface1 = IPInterface {
id: String::from("IP interface"),
connections: vec![],
listener,
};
let option_listener = net::TcpListener::bind("0.0.0.0:50000"); fn test() -> IFResult<()> {
let mut listener = match option_listener { let message = *b"Hello world from iron forest";
Ok(tmp) => tmp,
Err(_) => { let mut interface1 = IPInterface::new()?;
return; let mut interface2 = IPInterface::new()?;
}
};
let mut interface2 = IPInterface {
id: String::from("IP interface"),
connections: vec![],
listener,
};
let t1 = std::thread::spawn(move || { let t1 = std::thread::spawn(move || {
interface1.send(&[0, 0, 1, 1], Some(String::from("0.0.0.0:50000"))); interface1.send(&message, Some(String::from("127.0.0.1:50001"))).unwrap();
interface1 interface1
}); });
thread::sleep(Duration::from_millis(10));
let t2 = std::thread::spawn(move || { let t2 = std::thread::spawn(move || {
interface2.main_loop_iteration();
interface2.main_loop_iteration().unwrap();
interface2 interface2
}); });
let res1 = t1.join(); let res1 = t1.join();
match res1 { match res1 {
Ok(_) => println!("Ok"), Ok(_) => println!("Ok"),
Err(e) => println!("{:?}", e), Err(e) => println!("{:?}", e)
} }
let res2 = t2.join(); let res2 = t2.join();
match res2 { match res2 {
Ok(_) => println!("Ok"), Ok(_) => println!("Ok"),
Err(e) => println!("{:?}", e), Err(e) => println!("{:?}", e)
} }
// res1.unwrap(); Ok(())
} }
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]

165
src/interfaces/ip.rs

@ -1,19 +1,29 @@
use alloc::borrow::ToOwned;
use std::net; use std::net;
use std::thread;
use alloc::vec;
use alloc::vec::Vec; use alloc::vec::Vec;
use alloc::string::String; use alloc::string::{String, ToString};
use core::cmp::min;
use core::ops::RangeInclusive;
use core::str::from_utf8;
use core::time::Duration;
use crate::interface::{Interface, InterfaceRequirements, TargetingData}; use crate::interface::{Interface, InterfaceRequirements, TargetingData};
use crate::message::MessageBytes; use crate::message::MessageBytes;
use crate::res::{IFError, IFResult}; use crate::res::{IFError, IFResult};
use crate::res::IFError::General;
use crate::std::io::{Read, Write}; use crate::std::io::{Read, Write};
use crate::std::println; use crate::std::println;
const SOCKET_RANGE: RangeInclusive<i32> = 50000..=50010;
/// Interface for interactions using tcp sockets /// Interface for interactions using tcp sockets
pub struct IPInterface { pub struct IPInterface {
pub id: String, id: String,
pub connections: Vec<net::TcpStream>, connections: Vec<net::TcpStream>,
pub listener: net::TcpListener, listener: net::TcpListener,
peers: Vec<net::IpAddr>,
} }
impl InterfaceRequirements for IPInterface {} impl InterfaceRequirements for IPInterface {}
@ -21,41 +31,35 @@ impl InterfaceRequirements for IPInterface {}
impl Interface for IPInterface { impl Interface for IPInterface {
fn main_loop_iteration(&mut self) -> IFResult<()> { fn main_loop_iteration(&mut self) -> IFResult<()> {
println!("Mainloop {:?}", self.listener.local_addr()); println!("Mainloop {:?}", self.listener.local_addr());
println!("Incoming connections: {:?}", self.listener.incoming());
match self.listener.accept() { match self.listener.accept() {
Ok((stream, addr)) => { Ok((stream, addr)) => {
println!("New client: {:?}", addr); println!("New client: {:?}", addr);
self.connections.push(stream) self.connections.push(stream)
} }
Err(e) => println!("couldn't get client: {:?}", e), Err(e) => return Err(IFError::General(String::from("No incoming connection"))),
} }
// for stream in self.listener.incoming() {
// println!("Accepting stream...");
//
// match stream {
// Ok(stream) => {
// self.connections.push(stream);
// println!("Stream accepted");
// }
// Err(e) => { println!("Accepting failed"); return Err(IFError::General(String::from("Stream error"))); }
// }
// println!("End of cycle")
// }
println!("Hello from mainloop"); println!("Hello from mainloop");
for mut connection in &self.connections { for mut connection in &self.connections {
let mut size_arr: [u8; 4] = [0, 0, 0, 0]; let mut size_arr: [u8; 4] = [0, 0, 0, 0];
connection.read_exact(&mut size_arr)?; connection.read_exact(&mut size_arr)?;
let mut size: u32 = 0; let mut size = bytes_to_size(size_arr) as u32;
for size_byte in &size_arr {
size = size * 256 + *size_byte as u32;
} let mut message_take = connection.take(size as u64);
let mut message: Vec<u8> = vec![];
message_take.read_to_end(&mut message);
println!("Size: {:?}", size); println!("Size: {:?}", size);
println!("Message: {:?}", from_utf8(&*message));
} }
Ok(()) Ok(())
} }
fn has_blocking_main(&self) -> bool { fn has_blocking_main(&self) -> bool {
true false
} }
fn id(&self) -> &str { fn id(&self) -> &str {
&*self.id &*self.id
@ -63,18 +67,31 @@ impl Interface for IPInterface {
fn send(&mut self, message: &[u8], interface_data: Option<TargetingData>) -> IFResult<()> { fn send(&mut self, message: &[u8], interface_data: Option<TargetingData>) -> IFResult<()> {
let addr: net::SocketAddr = match interface_data { let addr: net::SocketAddr = match interface_data {
Some(ip_string) => ip_string.parse().expect("Unable to parse address"), Some(ip_string) => ip_string.parse().expect("Unable to parse address"),
None => return Err(IFError::General(String::from("Not enough info to create connection"))) None => return Err(IFError::General(String::from("Not enough info to create connections")))
}; };
println!("Connecting to {:?}", addr); println!("Connecting to {:?}", addr);
let index = match self.connections.iter().position(|connection| connection.peer_addr().ok() == Some(addr)) { let index = match self.connections.iter().position(|connection| connection.peer_addr().ok() == Some(addr)) {
None => { None => {
self.connections.push(net::TcpStream::connect(addr)?); let connection = match net::TcpStream::connect_timeout(
&addr,
Duration::new(1, 0)
) {
Ok(connection) => connection,
Err(_) => return Err(General(String::from("Can't connect to this port")))
};
self.connections.push(connection);
self.connections.len() - 1 self.connections.len() - 1
} }
Some(i) => i Some(i) => i
}; };
println!("Sending message to {:?}", self.connections[index].peer_addr().unwrap()); println!("Sending message to {:?}", self.connections[index].peer_addr().unwrap());
self.connections[index].set_write_timeout(Some(Duration::new(1, 0)))?;
self.connections[index].write_all(&size_to_bytes(message.len()))?;
self.connections[index].write_all(message)?; self.connections[index].write_all(message)?;
println!("Sent message"); println!("Sent message");
Ok(()) Ok(())
@ -82,49 +99,95 @@ impl Interface for IPInterface {
fn receive(&mut self) -> IFResult<Option<(MessageBytes, TargetingData)>> { todo!() } fn receive(&mut self) -> IFResult<Option<(MessageBytes, TargetingData)>> { todo!() }
} }
#[cfg(test)] impl IPInterface {
use alloc::vec; pub fn new() -> IFResult<Self> {
let mut listener = match create_tcp_listener() {
Some(listener) => listener,
None => {
return Err(IFError::General(String::from("Unable to open TCP listener")));
}
};
#[test] listener.set_nonblocking(true)?;
fn test_creating_connection() {
let listener = match net::TcpListener::bind("0.0.0.0:60000") {
Ok(tmp) => tmp,
Err(_) => { return; }
};
let mut interface1 = IPInterface {
id: String::from("IP interface"),
connections: vec![],
listener,
};
let listener = match net::TcpListener::bind("0.0.0.0:50000") { Ok(IPInterface {
Ok(tmp) => tmp, id: String::from("IP Interface"),
Err(_) => { return; } connections: vec!(),
}; listener,
let mut interface2 = IPInterface { peers: vec!(),
id: String::from("IP interface"), })
connections: vec![], }
listener, pub fn dump(&self) -> IFResult<Vec<u8>> {
Ok(serde_cbor::to_vec(&self.peers)?)
}
pub fn load(&mut self, data: Vec<u8>) -> IFResult<()> {
let peers: Vec<net::IpAddr> = serde_cbor::from_slice(&data)?;
self.peers = peers;
Ok(())
}
}
fn create_tcp_listener() -> Option<net::TcpListener> {
for port in SOCKET_RANGE {
match net::TcpListener::bind("127.0.0.1:".to_owned() + &port.to_string()) {
Ok(listener) => return Some(listener),
Err(e) => {}
}
}; };
None
}
fn size_to_bytes(mut a: usize) -> [u8; 4] {
let mut arr: [u8; 4] = [0, 0, 0, 0];
for i in [3, 2, 1, 0] {
arr[i] = (a % 256) as u8;
a /= 256;
}
arr
}
fn bytes_to_size(arr: [u8; 4]) -> usize {
let mut size = 0;
for size_byte in &arr {
size = size * 256 + *size_byte as u32;
}
size as usize
}
#[test]
fn test_creating_connection() -> IFResult<()> {
let message = *b"Hello world from iron forest";
let mut interface1 = IPInterface::new()?;
let mut interface2 = IPInterface::new()?;
let t1 = std::thread::spawn(move || { let t1 = std::thread::spawn(move || {
interface1.send(&[0, 0, 1, 1], Some(String::from("0.0.0.0:50000"))).unwrap(); interface1.send(&message, Some(String::from("127.0.0.1:50000")))
interface1
}); });
thread::sleep(Duration::from_millis(10));
let t2 = std::thread::spawn(move || { let t2 = std::thread::spawn(move || {
interface2.main_loop_iteration().unwrap(); interface2.main_loop_iteration()
interface2
}); });
let res1 = t1.join(); let res1 = t1.join();
match res1 { match res1 {
Ok(_) => println!("Ok"), Ok(res) => {
println!("Thread Ok");
println!("interface1: {:?}", res)
},
Err(e) => println!("{:?}", e) Err(e) => println!("{:?}", e)
} }
let res2 = t2.join(); let res2 = t2.join();
match res2 { match res2 {
Ok(_) => println!("Ok"), Ok(res) => {
println!("Thread Ok");
println!("interface2: {:?}", res)
},
Err(e) => println!("{:?}", e) Err(e) => println!("{:?}", e)
} }
Ok(())
} }
#[cfg(test)] #[cfg(test)]

2
src/lib.rs

@ -17,7 +17,7 @@ mod message;
mod transport; mod transport;
pub mod interface; pub mod interface;
pub mod interfaces; pub mod interfaces;
mod res; pub mod res;
mod tunnel; mod tunnel;
#[cfg(std)] #[cfg(std)]

Loading…
Cancel
Save