Skip to content
Snippets Groups Projects
Commit 1de7f2ad authored by jkerdreu's avatar jkerdreu
Browse files

- Switch to low level API to enable SO_REUSEPORT (default Multicast socket doesn´t support this)

git-svn-id: https://redmine.imt-atlantique.fr/svn/xaal/code/Java/branches/0.7@3101 b32b6428-25c9-4566-ad07-03861ab6144f
parent ed547297
Branches
No related tags found
No related merge requests found
......@@ -2,12 +2,22 @@ package imt.xaal.lib;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.StandardProtocolFamily;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.MembershipKey;
import java.io.*;
import java.util.Arrays;
import java.util.Queue;
import java.util.logging.Logger;
import imt.xaal.utils.BinUtils;
import imt.xaal.utils.NetworkUtils;
/**
*
* @author jkx
......@@ -16,7 +26,8 @@ public final class NetworkConnector extends Thread {
private final static Logger LOGGER = Logger.getLogger(NetworkConnector.class.getName());
MulticastSocket msocket;
private DatagramChannel dgChannel;
private InetAddress groupAddr;
private int port;
private int ttl;
......@@ -24,7 +35,6 @@ public final class NetworkConnector extends Thread {
private Queue<byte[]> fifoOUT = null;
public NetworkConnector(String addr, int port, int ttl) throws IOException {
msocket = new MulticastSocket();
setAddr(InetAddress.getByName(addr));
setPort(port);
setHops(ttl);
......@@ -82,24 +92,30 @@ public final class NetworkConnector extends Thread {
*/
public void setHops(int hops) {
this.ttl = hops;
try {
this.msocket.setTimeToLive(hops);
} catch (IOException e) {
LOGGER.severe(e.getMessage());
}
}
public void connect() throws IOException {
String ifaceName = NetworkUtils.getDefaultNetworkInterface();
NetworkInterface iface = NetworkInterface.getByName(ifaceName);
InetAddress addr = getAddr();
int port = getPort();
this.msocket = new MulticastSocket(port);
this.msocket.joinGroup(addr);
int hops = getHops();
this.dgChannel = DatagramChannel.open(StandardProtocolFamily.INET);
this.dgChannel.setOption(StandardSocketOptions.SO_REUSEPORT, true);
this.dgChannel.bind(new InetSocketAddress(port));
this.dgChannel.setOption(StandardSocketOptions.IP_MULTICAST_IF, iface);
this.dgChannel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, hops);
this.dgChannel.join(addr, iface);
LOGGER.info("Connnecting " + addr.toString() + ":" + port);
}
public void disconnect() {
try {
this.msocket.leaveGroup(getAddr());
this.dgChannel.close();
} catch (IOException e) {
LOGGER.severe(e.getMessage());
}
......@@ -107,23 +123,23 @@ public final class NetworkConnector extends Thread {
}
public void send(byte[] data) {
InetSocketAddress target = new InetSocketAddress(getAddr(),getPort());
try {
DatagramPacket msgTx = new DatagramPacket(data, data.length, getAddr(), port);
this.msocket.send(msgTx);
this.dgChannel.send(ByteBuffer.wrap(data), target);
} catch (IOException e) {
LOGGER.severe(e.getMessage());
}
}
public byte[] receive() {
byte[] buf = new byte[16384];
DatagramPacket data = new DatagramPacket(buf, buf.length);
ByteBuffer buf = ByteBuffer.allocate(65507);
try {
this.msocket.receive(data);
this.dgChannel.receive(buf);
} catch (IOException e) {
LOGGER.severe(e.getMessage());
}
return Arrays.copyOfRange(buf, 0, data.getLength());
byte[] data = new byte[ buf.position() ]; buf.rewind(); buf.get(data);
return data;
}
public void setOUTFifo(Queue<byte[]> value) {
......
package imt.xaal.utils;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.logging.Logger;
import imt.xaal.lib.NetworkConnector;
public final class NetworkUtils {
private final static Logger LOGGER = Logger.getLogger(NetworkConnector.class.getName());
public static String getDefaultNetworkInterface() {
// https://stackoverflow.com/questions/42102601/getting-the-default-network-interface-via-java
final String globalHost = "a.root-servers.net"; // Must exist.
String name = null;
InetAddress remoteAddress = null;
try {
remoteAddress = InetAddress.getByName(globalHost);
} catch (UnknownHostException e) {
LOGGER.warning("Unable to resolve " + globalHost);
}
if (remoteAddress != null) {
try (DatagramSocket s = new DatagramSocket()) {
// UDP does not actually open a connection, we just need to do this to get the
// interface we would send packets on if we actually tried.
s.connect(remoteAddress, 80);
name = NetworkInterface.getByInetAddress(s.getLocalAddress()).getName();
} catch (SocketException e) {
LOGGER.warning("Unable to get default network interface");
}
}
return name;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment