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