Implement AutoConnect
This commit is contained in:
parent
99ef2a8edc
commit
adc8725a36
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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(())
|
||||||
|
}
|
Loading…
Reference in New Issue