Skip to content
Snippets Groups Projects
Commit 4f4e06cb authored by Brutzman, Don's avatar Brutzman, Don
Browse files

socket.joinGroup updated to include networkInterface

parent 37b02730
No related branches found
No related tags found
No related merge requests found
package OpenDis4Examples; package OpenDis4Examples;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.util.*; import java.util.*;
import edu.nps.moves.dis.*; import edu.nps.moves.dis.*;
import edu.nps.moves.disutil.CoordinateConversions; import edu.nps.moves.disutil.CoordinateConversions;
import edu.nps.moves.disutil.DisTime; import edu.nps.moves.disutil.DisTime;
/** /**
* Creates and sends ESPDUs in IEEE binary format. Adapted from OpenDIS library * Creates and sends ESPDUs in IEEE binary format. Adapted from OpenDIS library
* example package edu.nps.moves.examples * example package edu.nps.moves.examples
* *
* @author DMcG * @author DMcG
*/ */
public class EspduSender { public class EspduSender {
/** Defining number of packets to send is superior to infinite loops /** Defining number of packets to send is superior to infinite loops
* which have possible hazard of unstoppably sending packets as a zombie process */ * which have possible hazard of unstoppably sending packets as a zombie process */
public static final int NUMBER_TO_SEND = 5000; public static final int NUMBER_TO_SEND = 5000;
/** Type of network connection */ /** Type of network connection */
public enum NetworkMode { public enum NetworkMode {
/** @see <a href="https://en.wikipedia.org/wiki/Unicast">https://en.wikipedia.org/wiki/Unicast</a> */ /** @see <a href="https://en.wikipedia.org/wiki/Unicast">https://en.wikipedia.org/wiki/Unicast</a> */
UNICAST, UNICAST,
/** @see <a href="https://en.wikipedia.org/wiki/Multicast">https://en.wikipedia.org/wiki/Multicast</a> */ /** @see <a href="https://en.wikipedia.org/wiki/Multicast">https://en.wikipedia.org/wiki/Multicast</a> */
MULTICAST, MULTICAST,
/** @see <a href="https://en.wikipedia.org/wiki/Broadcasting_(networking)">https://en.wikipedia.org/wiki/Broadcasting_(networking)</a> */ /** @see <a href="https://en.wikipedia.org/wiki/Broadcasting_(networking)">https://en.wikipedia.org/wiki/Broadcasting_(networking)</a> */
BROADCAST BROADCAST
}; };
/** /**
* Default multicast group address we send on. * Default multicast group address we send on.
*/ */
public static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3"; public static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3";
/** /**
* Default multicast port used, matches Wireshark DIS capture default * Default multicast port used, matches Wireshark DIS capture default
* @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)">https://en.wikipedia.org/wiki/Port_(computer_networking)</a>
*/ */
public static final int DEFAULT_MULTICAST_PORT = 3000; public static final int DEFAULT_MULTICAST_PORT = 3000;
/** /**
* Possible system properties, passed in via -Dattr=val networkMode: * Possible system properties, passed in via -Dattr=val networkMode:
* unicast, broadcast, multicast destinationIp: where to send the packet. If * unicast, broadcast, multicast destinationIp: where to send the packet. If
* in multicast mode, this can be multicast. To determine broadcast * in multicast mode, this can be multicast. To determine broadcast
* destination IP, use an online broadcast address calculator, for example * destination IP, use an online broadcast address calculator, for example
* http://www.remotemonitoringsystems.ca/broadcast.php If in multicast mode, * http://www.remotemonitoringsystems.ca/broadcast.php If in multicast mode,
* a join() will be done on the multicast address. port: port used for both * a join() will be done on the multicast address. port: port used for both
* source and destination. * source and destination.
* *
* @param args command-line arguments * @param args command-line arguments
*/ */
public static void main(String args[]) public static void main(String args[])
{ {
System.out.println("OpenDis4Examples.EspduSender started... send " + NUMBER_TO_SEND + " ESPDUs, initial index=0"); System.out.println("OpenDis4Examples.EspduSender started... send " + NUMBER_TO_SEND + " ESPDUs, initial index=0");
/** /**
* an entity state pdu * an entity state pdu
*/ */
EntityStatePdu espdu = new EntityStatePdu(); EntityStatePdu espdu = new EntityStatePdu();
MulticastSocket socket = null; // must be initialized, even if null MulticastSocket socket = null; // must be initialized, even if null
DisTime disTime = DisTime.getInstance(); // TODO explain DisTime disTime = DisTime.getInstance(); // TODO explain
int alternator = -1; int alternator = -1;
// ICBM coordinates for my office // ICBM coordinates for my office
double lat = 36.595517; double lat = 36.595517;
double lon = -121.877000; double lon = -121.877000;
// Default settings. These are used if no system properties are set. // Default settings. These are used if no system properties are set.
// If system properties are passed in, these are over ridden. // If system properties are passed in, these are over ridden.
int port = DEFAULT_MULTICAST_PORT; int port = DEFAULT_MULTICAST_PORT;
NetworkMode mode = NetworkMode.BROADCAST; NetworkMode mode = NetworkMode.BROADCAST;
InetAddress destinationIp = null; // must be initialized, even if null InetAddress destinationIp = null; // must be initialized, even if null
try { try {
destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS);
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
System.out.println(e + " Cannot create multicast address"); System.out.println(e + " Cannot create multicast address");
System.exit(0); System.exit(0);
} }
// All system properties, passed in on the command line via -Dattribute=value // All system properties, passed in on the command line via -Dattribute=value
Properties systemProperties = System.getProperties(); Properties systemProperties = System.getProperties();
// IP address we send to // IP address we send to
String destinationIpString = systemProperties.getProperty("destinationIp"); String destinationIpString = systemProperties.getProperty("destinationIp");
// Port we send to, and local port we open the socket on // Port we send to, and local port we open the socket on
String portString = systemProperties.getProperty("port"); String portString = systemProperties.getProperty("port");
// Network mode: unicast, multicast, broadcast // Network mode: unicast, multicast, broadcast
String networkModeString = systemProperties.getProperty("networkMode"); // unicast or multicast or broadcast String networkModeString = systemProperties.getProperty("networkMode"); // unicast or multicast or broadcast
// Set up a socket to send information // Set up a socket to send information
try { try {
// Port we send to // Port we send to
if (portString != null) if (portString != null)
{ {
port = Integer.parseInt(portString); System.out.println("Using systemProperties port=" + portString);
} port = Integer.parseInt(portString);
}
socket = new MulticastSocket(port);
socket = new MulticastSocket(port);
// Where we send packets to, the destination IP address
if (destinationIpString != null) // Where we send packets to, the destination IP address
{ if (destinationIpString != null)
destinationIp = InetAddress.getByName(destinationIpString); {
} destinationIp = InetAddress.getByName(destinationIpString);
}
// Type of transport: unicast, broadcast, or multicast
// TODO convert to String constants // Type of transport: unicast, broadcast, or multicast
if (networkModeString != null) { // TODO convert to String constants
if (networkModeString.equalsIgnoreCase("unicast")) if (networkModeString != null) {
{ if (networkModeString.equalsIgnoreCase("unicast"))
mode = NetworkMode.UNICAST; {
} mode = NetworkMode.UNICAST;
else if (networkModeString.equalsIgnoreCase("broadcast")) { }
mode = NetworkMode.BROADCAST; else if (networkModeString.equalsIgnoreCase("broadcast")) {
} mode = NetworkMode.BROADCAST;
else if (networkModeString.equalsIgnoreCase("multicast")) { }
mode = NetworkMode.MULTICAST; else if (networkModeString.equalsIgnoreCase("multicast")) {
if (!destinationIp.isMulticastAddress()) mode = NetworkMode.MULTICAST;
{ if (!destinationIp.isMulticastAddress())
throw new RuntimeException("Sending to multicast address, but destination address " + destinationIp.toString() + "is not multicast"); {
} throw new RuntimeException("Sending to multicast address, but destination address " + destinationIp.toString() + "is not multicast");
socket.joinGroup(destinationIp); }
} // socket.joinGroup(destinationIp); // deprecated, TODO select correct NetworkInterface
} // end networkModeString // =======================================================================
} // updated approach using NetworkInterface
catch (IOException | RuntimeException e) NetworkInterface networkInterface = NetworkInterface.getByInetAddress(destinationIp);
{ if (networkInterface != null)
System.out.println("Unable to initialize networking. Exiting."); System.out.println("networkInterface=" + networkInterface.getDisplayName()); // typically null if loopback
System.out.println(e); SocketAddress localMulticastSocketAddress = new InetSocketAddress(destinationIp, DEFAULT_MULTICAST_PORT);
System.exit(-1); MulticastSocket multicastSocket = new MulticastSocket(DEFAULT_MULTICAST_PORT);
} multicastSocket.joinGroup(localMulticastSocketAddress, networkInterface);
// =======================================================================
// Initialize values in the Entity State PDU object. The exercise ID is }
// a way to differentiate between different virtual worlds on one network. } // end networkModeString
// Note that some values (such as the PDU type and PDU family) are set }
// automatically when you create the ESPDU. catch (IOException | RuntimeException e)
espdu.setExerciseID((short) 1); {
System.out.println("Unable to initialize networking. Exiting.");
// The EID is the unique identifier for objects in the world. This System.out.println(e);
// EID should match up with the ID for the object specified in the System.exit(-1);
// VMRL/x3d/virtual world. }
EntityID entityID = espdu.getEntityID();
entityID.setSite(1); // 0 is apparently not a valid site number, per the spec // Initialize values in the Entity State PDU object. The exercise ID is
entityID.setApplication(1); // a way to differentiate between different virtual worlds on one network.
entityID.setEntity(2); // Note that some values (such as the PDU type and PDU family) are set
// automatically when you create the ESPDU.
// Set the entity type. SISO has a big list of enumerations, so that by espdu.setExerciseID((short) 1);
// specifying various numbers we can say this is an M1A2 American tank,
// the USS Enterprise, and so on. We'll make this a tank. There is a // The EID is the unique identifier for objects in the world. This
// separate project elsehwhere in this project that implements DIS // EID should match up with the ID for the object specified in the
// enumerations in C++ and Java, but to keep things simple we just use // VMRL/x3d/virtual world.
// numbers here. EntityID entityID = espdu.getEntityID();
EntityType entityType = espdu.getEntityType(); entityID.setSite(1); // 0 is apparently not a valid site number, per the spec
entityType.setEntityKind((short) 1); // Platform (vs lifeform, munition, sensor, etc.) entityID.setApplication(1);
entityType.setCountry(225); // USA entityID.setEntity(2);
entityType.setDomain((short) 1); // Land (vs air, surface, subsurface, space)
entityType.setCategory((short) 1); // Tank // Set the entity type. SISO has a big list of enumerations, so that by
entityType.setSubcategory((short) 1); // M1 Abrams // specifying various numbers we can say this is an M1A2 American tank,
entityType.setSpec((short) 3); // M1A2 Abrams // the USS Enterprise, and so on. We'll make this a tank. There is a
// separate project elsehwhere in this project that implements DIS
Set<InetAddress> broadcastAddresses; // enumerations in C++ and Java, but to keep things simple we just use
// Loop through sending N ESPDUs // numbers here.
try EntityType entityType = espdu.getEntityType();
{ entityType.setEntityKind((short) 1); // Platform (vs lifeform, munition, sensor, etc.)
System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString()); entityType.setCountry(225); // USA
entityType.setDomain((short) 1); // Land (vs air, surface, subsurface, space)
for (int index = 0; index < NUMBER_TO_SEND; index++) { entityType.setCategory((short) 1); // Tank
// DIS time is a pain in the uh, neck. DIS time units are 2^31-1 units per entityType.setSubcategory((short) 1); // M1 Abrams
// hour, and time is set to DIS time units from the top of the hour. entityType.setSpec((short) 3); // M1A2 Abrams
// This means that if you start sending just before the top of the hour
// the time units can roll over to zero as you are sending. The receivers Set<InetAddress> broadcastAddresses;
// (escpecially homegrown ones) are often not able to detect rollover // Loop through sending N ESPDUs
// and may start discarding packets as dupes or out of order. We use try
// an NPS timestamp here, hundredths of a second since the start of the {
// year. The DIS standard for time is often ignored in the wild; I've seen System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString());
// people use Unix time (seconds since 1970) and more. Or you can
// just stuff idx into the timestamp field to get something that is monotonically for (int index = 0; index < NUMBER_TO_SEND; index++) {
// increasing. // DIS time is a pain in the uh, neck. DIS time units are 2^31-1 units per
// hour, and time is set to DIS time units from the top of the hour.
// Note that timestamp is used to detect duplicate and out of order packets. // This means that if you start sending just before the top of the hour
// That means if you DON'T change the timestamp, many implementations will simply // the time units can roll over to zero as you are sending. The receivers
// discard subsequent packets that have an identical timestamp. Also, if they // (escpecially homegrown ones) are often not able to detect rollover
// receive a PDU with an timestamp lower than the last one they received, they // and may start discarding packets as dupes or out of order. We use
// may discard it as an earlier, out-of-order PDU. So it is a good idea to // an NPS timestamp here, hundredths of a second since the start of the
// update the timestamp on ALL packets sent. // year. The DIS standard for time is often ignored in the wild; I've seen
// An alterative approach: actually follow the standard. It's a crazy concept, // people use Unix time (seconds since 1970) and more. Or you can
// but it might just work. // just stuff idx into the timestamp field to get something that is monotonically
int timestamp = disTime.getDisAbsoluteTimestamp(); // increasing.
espdu.setTimestamp(timestamp);
// Note that timestamp is used to detect duplicate and out of order packets.
// Set the position of the entity in the world. DIS uses a cartesian // That means if you DON'T change the timestamp, many implementations will simply
// coordinate system with the origin at the center of the earth, the x // discard subsequent packets that have an identical timestamp. Also, if they
// axis out at the equator and prime meridian, y out at the equator and // receive a PDU with an timestamp lower than the last one they received, they
// 90 deg east, and z up and out the north pole. To place an object on // may discard it as an earlier, out-of-order PDU. So it is a good idea to
// the earth's surface you also need a model for the shape of the earth // update the timestamp on ALL packets sent.
// (it's not a sphere.) All the fancy math necessary to do this is in // An alterative approach: actually follow the standard. It's a crazy concept,
// the SEDRIS SRM package. There are also some one-off formulas for // but it might just work.
// doing conversions from, for example, lat/lon/altitude to DIS coordinates. int timestamp = disTime.getDisAbsoluteTimestamp();
// Here we use those one-off formulas. espdu.setTimestamp(timestamp);
// Modify the position of the object. This will send the object a little
// due east by adding some to the longitude every iteration. Since we // Set the position of the entity in the world. DIS uses a cartesian
// are on the Pacific coast, this sends the object east. Assume we are // coordinate system with the origin at the center of the earth, the x
// at zero altitude. In other worlds you'd use DTED to determine the // axis out at the equator and prime meridian, y out at the equator and
// local ground altitude at that lat/lon, or you'd just use ground clamping. // 90 deg east, and z up and out the north pole. To place an object on
// The x and y values will change, but the z value should not. // the earth's surface you also need a model for the shape of the earth
//lon = lon + (double)((double)idx / 100000.0); // (it's not a sphere.) All the fancy math necessary to do this is in
//System.out.println("lla=" + lat + "," + lon + ", 0.0"); // the SEDRIS SRM package. There are also some one-off formulas for
double direction = Math.pow((double) (-1.0), (double) (index)); // doing conversions from, for example, lat/lon/altitude to DIS coordinates.
lon = lon + (direction * 0.00006); // Here we use those one-off formulas.
System.out.println(lon); // Modify the position of the object. This will send the object a little
// due east by adding some to the longitude every iteration. Since we
double disCoordinates[] = CoordinateConversions.getXYZfromLatLonDegrees(lat, lon, 1.0); // are on the Pacific coast, this sends the object east. Assume we are
Vector3Double location = espdu.getEntityLocation(); // at zero altitude. In other worlds you'd use DTED to determine the
location.setX(disCoordinates[0]); // local ground altitude at that lat/lon, or you'd just use ground clamping.
location.setY(disCoordinates[1]); // The x and y values will change, but the z value should not.
location.setZ(disCoordinates[2]); //lon = lon + (double)((double)idx / 100000.0);
System.out.println("lat, lon:" + lat + ", " + lon); //System.out.println("lla=" + lat + "," + lon + ", 0.0");
System.out.println("DIS coord:" + disCoordinates[0] + ", " + disCoordinates[1] + ", " + disCoordinates[2]); double direction = Math.pow((double) (-1.0), (double) (index));
lon = lon + (direction * 0.00006);
// Optionally, we can do some rotation of the entity System.out.println(lon);
/*
Orientation orientation = espdu.getEntityOrientation(); double disCoordinates[] = CoordinateConversions.getXYZfromLatLonDegrees(lat, lon, 1.0);
float psi = orientation.getPsi(); Vector3Double location = espdu.getEntityLocation();
psi = psi + idx; location.setX(disCoordinates[0]);
orientation.setPsi(psi); location.setY(disCoordinates[1]);
orientation.setTheta((float)(orientation.getTheta() + idx /2.0)); location.setZ(disCoordinates[2]);
*/ System.out.println("lat, lon:" + lat + ", " + lon);
// You can set other ESPDU values here, such as the velocity, acceleration, System.out.println("DIS coord:" + disCoordinates[0] + ", " + disCoordinates[1] + ", " + disCoordinates[2]);
// and so on.
// Marshal out the espdu object to a byte array, then send a datagram // Optionally, we can do some rotation of the entity
// packet with that data in it. /*
ByteArrayOutputStream baos = new ByteArrayOutputStream(); Orientation orientation = espdu.getEntityOrientation();
DataOutputStream dos = new DataOutputStream(baos); float psi = orientation.getPsi();
espdu.marshal(dos); psi = psi + idx;
orientation.setPsi(psi);
FirePdu fire = new FirePdu(); orientation.setTheta((float)(orientation.getTheta() + idx /2.0));
byte[] fireArray = fire.marshal(); */
// You can set other ESPDU values here, such as the velocity, acceleration,
// The byte array here is the packet in DIS format. We put that into a // and so on.
// datagram and send it. // Marshal out the espdu object to a byte array, then send a datagram
byte[] data = baos.toByteArray(); // packet with that data in it.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
broadcastAddresses = getBroadcastAddresses(); DataOutputStream dos = new DataOutputStream(baos);
Iterator iterator = broadcastAddresses.iterator(); espdu.marshal(dos);
while (iterator.hasNext())
{ FirePdu fire = new FirePdu();
InetAddress broadcast = (InetAddress) iterator.next(); byte[] fireArray = fire.marshal();
System.out.println("Sending broadcast datagram packet to " + broadcast);
DatagramPacket packet = new DatagramPacket(data, data.length, broadcast, port); // The byte array here is the packet in DIS format. We put that into a
socket.send(packet); // datagram and send it.
// TODO experiment with these! 8) byte[] data = baos.toByteArray();
packet = new DatagramPacket(fireArray, fireArray.length, broadcast, port); // alternate
socket.send(packet); broadcastAddresses = getBroadcastAddresses();
} Iterator iterator = broadcastAddresses.iterator();
while (iterator.hasNext())
// Send every 1 sec. Otherwise all this will be all over in a fraction of a second. {
Thread.sleep(1000); // msec InetAddress broadcast = (InetAddress) iterator.next();
System.out.println("Sending broadcast datagram packet to " + broadcast);
location = espdu.getEntityLocation(); DatagramPacket packet = new DatagramPacket(data, data.length, broadcast, port);
socket.send(packet);
System.out.println("Espdu #" + index + " EID=[" + entityID.getSite() + "," + entityID.getApplication() + "," + entityID.getEntity() + "]"); // TODO experiment with these! 8)
System.out.println(" DIS coordinates location=[" + location.getX() + "," + location.getY() + "," + location.getZ() + "]"); packet = new DatagramPacket(fireArray, fireArray.length, broadcast, port); // alternate
double c[] = {location.getX(), location.getY(), location.getZ()}; socket.send(packet);
double lla[] = CoordinateConversions.xyzToLatLonDegrees(c); }
// debug: System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
} // Send every 1 sec. Otherwise all this will be all over in a fraction of a second.
} Thread.sleep(1000); // msec
catch (IOException | InterruptedException e)
{ location = espdu.getEntityLocation();
System.out.println("Problem with OpenDis4Examples.EspduSender, see exception trace:");
System.out.println(e); System.out.println("Espdu #" + index + " EID=[" + entityID.getSite() + "," + entityID.getApplication() + "," + entityID.getEntity() + "]");
} System.out.println(" DIS coordinates location=[" + location.getX() + "," + location.getY() + "," + location.getZ() + "]");
} double c[] = {location.getX(), location.getY(), location.getZ()};
double lla[] = CoordinateConversions.xyzToLatLonDegrees(c);
/** // debug: System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
* A number of sites get all snippy about using 255.255.255.255 for a }
* broadcast address; it trips their security software and they kick you off }
* their network. (Comcast, NPS.) This determines the broadcast address for catch (IOException | InterruptedException e)
* all connected interfaces, based on the IP and subnet mask. If you have a {
* dual-homed host it will return a broadcast address for both. If you have System.out.println("Problem with OpenDis4Examples.EspduSender, see exception trace:");
* some VMs running on your host this will pick up the addresses for those System.out.println(e);
* as well--e.g. running VMWare on your laptop with a local IP this will also }
* pick up a 192.168 address assigned to the VM by the host OS. }
*
* @return set of all broadcast addresses /**
*/ * A number of sites get all snippy about using 255.255.255.255 for a
public static Set<InetAddress> getBroadcastAddresses() * broadcast address; it trips their security software and they kick you off
{ * their network. (Comcast, NPS.) This determines the broadcast address for
Set<InetAddress> broadcastAddresses = new HashSet<>(); * all connected interfaces, based on the IP and subnet mask. If you have a
Enumeration interfaces; * dual-homed host it will return a broadcast address for both. If you have
* some VMs running on your host this will pick up the addresses for those
try { * as well--e.g. running VMWare on your laptop with a local IP this will also
interfaces = NetworkInterface.getNetworkInterfaces(); * pick up a 192.168 address assigned to the VM by the host OS.
*
while (interfaces.hasMoreElements()) * @return set of all broadcast addresses
{ */
NetworkInterface anInterface = (NetworkInterface) interfaces.nextElement(); public static Set<InetAddress> getBroadcastAddresses()
{
if (anInterface.isUp()) Set<InetAddress> broadcastAddresses = new HashSet<>();
{ Enumeration interfaces;
Iterator iterator = anInterface.getInterfaceAddresses().iterator();
while (iterator.hasNext()) try {
{ interfaces = NetworkInterface.getNetworkInterfaces();
InterfaceAddress anAddress = (InterfaceAddress) iterator.next();
if ((anAddress == null || anAddress.getAddress().isLinkLocalAddress())) while (interfaces.hasMoreElements())
{ {
continue; NetworkInterface anInterface = (NetworkInterface) interfaces.nextElement();
}
if (anInterface.isUp())
//System.out.println("Getting broadcast address for " + anAddress); {
InetAddress broadcastAddress = anAddress.getBroadcast(); Iterator iterator = anInterface.getInterfaceAddresses().iterator();
if (broadcastAddress != null) while (iterator.hasNext())
{ {
broadcastAddresses.add(broadcastAddress); InterfaceAddress anAddress = (InterfaceAddress) iterator.next();
} if ((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
} {
} continue;
} }
}
catch (SocketException e) //System.out.println("Getting broadcast address for " + anAddress);
{ InetAddress broadcastAddress = anAddress.getBroadcast();
System.out.println("Problem with OpenDis4Examples.EspduSender.getBroadcastAddresses(), see exception trace:"); if (broadcastAddress != null)
System.out.println(e); {
} broadcastAddresses.add(broadcastAddress);
return broadcastAddresses; }
} }
} }
}
}
catch (SocketException e)
{
System.out.println("Problem with OpenDis4Examples.EspduSender.getBroadcastAddresses(), see exception trace:");
System.out.println(e);
}
return broadcastAddresses;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment