Implement AutoConnect

This commit is contained in:
CodeSteak 2019-06-05 17:05:34 +02:00
parent 99ef2a8edc
commit adc8725a36
2 changed files with 93 additions and 0 deletions

View File

@ -0,0 +1,48 @@
package org.hso.texturesyncclient.controller.net
import java.io.IOException
import java.lang.Exception
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress
class AutoConnect {
private constructor() {}
companion object {
@Throws(IOException::class)
fun search_server(mulicastAddr: String = "ff02::dd42:c0fe", port: Int = 10796, timeoutMs : Int = 4000): Connection {
val sock = DatagramSocket()
try {
sock.soTimeout = timeoutMs
val bytes = "TextureSync".toByteArray()
sock.send(
DatagramPacket(
bytes,
0,
bytes.size,
InetAddress.getByName(mulicastAddr),
port
)
)
// Response is PortNum in BE
val portData = ByteArray(2)
val response = DatagramPacket(portData, portData.size)
sock.receive(response)
// 2-Byte BE to Port Number
val port = (portData[0].toInt().shl(8)).or(portData[1].toInt())
return Connection(response.address, port)
} catch ( e : Exception) {
throw e
} finally {
sock.close()
}
}
}
}

View File

@ -0,0 +1,45 @@
use super::ProtocolConfig;
use std::thread;
use std::net::UdpSocket;
use std::io;
use std::net::SocketAddr;
use std::net::ToSocketAddrs;
use std::net::Ipv6Addr;
use std::str::FromStr;
pub fn start_autoconnect_server_async(cfg : &ProtocolConfig) -> io::Result<()> {
let cfg = cfg.clone();
let multi_sock = UdpSocket::bind((cfg.listen_addr.as_str(), cfg.port))?;
multi_sock.join_multicast_v6(
&Ipv6Addr::from_str(&cfg.autoconnect_multicastv6_addr).map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "Configured IPv6 addr. is invalid."))?,
0)?;
thread::spawn(move || {
let mut buffer = vec![0u8; 8096];
loop {
match multi_sock.recv_from(&mut buffer) {
Ok( (pkg_size, sender)) => {
respond(&multi_sock, &buffer[0..pkg_size], &sender, &cfg);
},
Err( e ) => {
println!("[Autoconnect] failed with : {:?}", e);
break;
}
}
};
});
Ok(())
}
fn respond(sock : &UdpSocket, input : &[u8], sender : &SocketAddr, cfg : &ProtocolConfig) -> io::Result<()> {
if input == b"TextureSync" {
println!("[Autoconnect] Got request from : {}", sender);
sock.send_to(&u16::to_be_bytes(cfg.port), sender)?;
}
Ok(())
}