Files
KLALB/src/org/kne/cloud/network/IPMulticastDiscovery.java
T

173 lines
4.8 KiB
Java

package org.kne.cloud.network;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.NoRouteToHostException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
public class IPMulticastDiscovery extends Thread implements Closeable, AutoCloseable {
private MulticastSocket soc;
private NetworkInterface ninterface;
private volatile boolean closed = false;
private InetSocketAddress group;
private InetSocketAddress bind;
private int type;
private List<MultipurposeSocketAddress> msas;
private volatile Consumer<MultipurposeSocketAddress> con;
public NetworkInterface getNinterface() {
return ninterface;
}
public InetSocketAddress getGroup() {
return group;
}
public InetSocketAddress getBind() {
return bind;
}
public Consumer<MultipurposeSocketAddress> getCon() {
return con;
}
public void setCon(Consumer<MultipurposeSocketAddress> con) {
this.con = con;
}
public IPMulticastDiscovery(InetSocketAddress bind, InetSocketAddress group, NetworkInterface ninterface,
List<MultipurposeSocketAddress> msas) throws IOException {
soc = new MulticastSocket(bind);
soc.joinGroup(group, ninterface);
this.bind = bind;
this.group = group;
this.ninterface = ninterface;
this.msas = msas;
}
@Override
public void run() {
Thread.currentThread().setName("线路发现线程");
ThreadTool.makeVDaemonThreadIfSupport("线路通知线程", () -> {
try {
while (!closed) {
HashSet<MultipurposeSocketAddress> s = new HashSet<MultipurposeSocketAddress>();
for (Iterator<MultipurposeSocketAddress> iterator = msas.iterator(); iterator.hasNext();) {
MultipurposeSocketAddress multipurposeSocketAddress = (MultipurposeSocketAddress) iterator
.next();
MultipurposeSocketAddress mpsa = new MultipurposeSocketAddress(
multipurposeSocketAddress.getType(), "::0", multipurposeSocketAddress.getPort());
try {
if (s.add(mpsa)) {
boolean bf = true;
Enumeration<InetAddress> ei = ninterface.getInetAddresses();
while (ei.hasMoreElements()) {
InetAddress inetAddress = (InetAddress) ei.nextElement();
if (inetAddress.equals(multipurposeSocketAddress.getInetAddress())) {
bf = false;
break;
}
}
if (bf) {
continue;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dops = new DataOutputStream(baos);
dops.writeInt(multipurposeSocketAddress.getPort());
dops.writeUTF(multipurposeSocketAddress.getType());
dops.close();
byte[] b = baos.toByteArray();
DatagramPacket dp = new DatagramPacket(b, b.length, group);
soc.send(dp);
}
} catch (NoRouteToHostException|UnknownHostException e) {
}
}
Thread.sleep(10000L);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} finally {
try {
close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
try {
loop:while (!closed) {
byte[] b = new byte[65535];
DatagramPacket dp = new DatagramPacket(b, b.length);
soc.receive(dp);
ByteArrayInputStream bis = new ByteArrayInputStream(b, 0, dp.getLength());
DataInputStream dis = new DataInputStream(bis);
int port = dis.readInt();
String type = dis.readUTF();
dis.close();
MultipurposeSocketAddress mpsa = new MultipurposeSocketAddress(type, dp.getAddress().getHostAddress(),
port);
//System.out.println(mpsa);
Enumeration<InetAddress> ei = ninterface.getInetAddresses();
while (ei.hasMoreElements()) {
InetAddress inetAddress = (InetAddress) ei.nextElement();
if (inetAddress.equals(mpsa.getInetAddress())) {
continue loop;
}
}
if (con != null) {
con.accept(mpsa);
}
}
} catch (IOException e) {
System.out.println(bind + " " + group + " " + ninterface);
e.printStackTrace();
} finally {
try {
close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void close() throws IOException {
soc.close();
closed = true;
}
public boolean isClosed() {
return closed;
}
}