1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
extern crate mio; pub use mio::udp::UdpSocket; use std::str::{FromStr, from_utf8}; use std::net::SocketAddr; pub fn open (address: &str) -> UdpSocket { let target = SocketAddr::from_str(address).unwrap(); let attempt = UdpSocket::bind(&target); match attempt { Err(why) => panic!("Could not bind to {}: {}", address, why), Ok(socket) => socket } } pub fn send (socket: &UdpSocket, message: &str, source: &str) { socket.set_broadcast(true).unwrap(); let bytes = message.to_string().into_bytes(); let source = SocketAddr::from_str(source).unwrap(); let result = socket.send_to(&bytes, &source); drop(socket); match result { Err(e) => panic!("Send error: {}", e), Ok(amount) => println!("Sent {} bytes to {}", amount.unwrap(), socket.local_addr().unwrap()) } } pub fn listen (socket: UdpSocket) -> Hub { Hub { socket: socket } } pub struct Hub { socket: UdpSocket } impl Iterator for Hub { type Item = String; fn next(&mut self) -> Option<String> { let message: String; loop { match self.socket.try_clone() { Err(why) => panic!("Socket error: {}", why), Ok(socket) => { match receive(socket) { None => continue, Some(msg) => { message = msg; break } } } } } Some(message) } } fn receive (socket: UdpSocket) -> Option<String> { let mut buffer: [u8; 2048] = [0; 2048]; let result = socket.recv_from(&mut buffer); drop(socket); match result { Err(e) => panic!("Receive error: {}", e), Ok(opt) => match opt { None => None, Some((amount, source)) => { println!("Received {} bytes from {}", amount, source); Some(format(buffer, amount, source)) } } } } fn format (buffer: [u8; 2048], amount: usize, source: SocketAddr) -> String { let body = from_utf8(&buffer[0..amount]).unwrap_or("{}"); format!("{{\"src\":\"{}\",\"msg\":{}}}", source.ip(), body) } #[cfg(test)] mod test { use std::{thread, time}; use super::*; #[test] fn single_message() { let socket = open("127.0.0.1:1905"); let receiver = listen(socket.try_clone().unwrap()); thread::sleep(time::Duration::from_millis(1500)); send(&socket, "{\"dit\":\"dat\"}", "127.0.0.1:1905"); for received in receiver { assert_eq!(received, "{\"src\":\"127.0.0.1\",\"msg\":{\"dit\":\"dat\"}}"); break } } }