Skip to content
Snippets Groups Projects
Commit ae609dbf authored by Terry D. Norbraten's avatar Terry D. Norbraten
Browse files

no object creation in loops, use NIO

parent 129c5bda
No related branches found
No related tags found
No related merge requests found
package UdpMulticastHttpExamples; package UdpMulticastHttpExamples;
import edu.nps.moves.dis7.utilities.DisThreadedNetIF;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
/** /**
* Looks a lot like UdpReceiver. Start this before launching MulticastSender. * Looks a lot like UdpReceiver. Start this before launching MulticastSender.
* *
* @author mcgredo * @author mcgredo
* @author brutzman * @author brutzman
...@@ -14,81 +18,97 @@ public class MulticastReceiver { ...@@ -14,81 +18,97 @@ public class MulticastReceiver {
// reserved range for all IPv4 multicast: 224.0.0.0 through 239.255.255.255 // reserved range for all IPv4 multicast: 224.0.0.0 through 239.255.255.255
// https://en.wikipedia.org/wiki/Multicast_address // https://en.wikipedia.org/wiki/Multicast_address
// https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml // https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
public static final String MULTICAST_ADDRESS = "239.1.2.15";
public static final String MULTICAST_ADDRESS = "239.1.2.15"; public static final int DESTINATION_PORT = 1718;
public static final int DESTINATION_PORT = 1718;
/** Time to live: how many router-decrement levels can be crossed */ /**
public static final int TTL = 10; * Time to live: how many router-decrement levels can be crossed
*/
final private static boolean infiniteReadLoop = true; public static final int TTL = 10;
public static void main(String[] args) private static final boolean INFINITE_READ_LOOP = true;
{ private static NetworkInterface ni;
try
{ public static void main(String[] args) {
System.out.println("MulticastReceiver started...");
MulticastSocket multicastSocket = null;
InetSocketAddress group = null;
ByteBuffer buffer = ByteBuffer.allocate(1500);
DatagramPacket packet = new DatagramPacket(buffer.array(), buffer.capacity());
try {
System.out.println("MulticastReceiver started...");
// This is a java/IPv6 problem. You should also add it to the // This is a java/IPv6 problem. You should also add it to the
// arguments used to start the app, eg -Djava.net.preferIPv4Stack=true // arguments used to start the app, eg -Djava.net.preferIPv4Stack=true
// set in the "run" section of preferences. Also, typically // set in the "run" section of preferences. Also, typically
// netbeans must be restarted after these settings. // netbeans must be restarted after these settings.
// https://stackoverflow.com/questions/18747134/getting-cant-assign-requested-address-java-net-socketexception-using-ehcache // https://stackoverflow.com/questions/18747134/getting-cant-assign-requested-address-java-net-socketexception-using-ehcache
System.setProperty("java.net.preferIPv4Stack", "true"); System.setProperty("java.net.preferIPv4Stack", "true");
MulticastSocket multicastSocket = new MulticastSocket(DESTINATION_PORT); multicastSocket = new MulticastSocket(DESTINATION_PORT);
multicastSocket.setTimeToLive(TTL); multicastSocket.setTimeToLive(TTL);
InetAddress multicastAddress = InetAddress.getByName(MULTICAST_ADDRESS); InetAddress multicastAddress = InetAddress.getByName(MULTICAST_ADDRESS);
group = new InetSocketAddress(multicastAddress, DESTINATION_PORT);
// Join group useful on receiving side // Join group useful on receiving side
multicastSocket.joinGroup(multicastAddress); multicastSocket.joinGroup(group, ni = DisThreadedNetIF.findIpv4Interface());
// You can join multiple groups here // You can join multiple groups here
System.out.println("Multicast address/port: " + multicastAddress.getHostAddress() + "/" + DESTINATION_PORT); System.out.println("Multicast address/port: " + multicastAddress.getHostAddress() + "/" + DESTINATION_PORT);
System.out.println("Multicast packets received log:"); System.out.println("Multicast packets received log:");
int count = 0; // initialize int index, count = 0; // initialize
float firstFloat, secondFloat;
while(true) StringBuilder firstCharacters = new StringBuilder();
{ char nextChar;
byte[] packetArray = new byte[1500]; // note use of typical MTU value
DatagramPacket packet = new DatagramPacket(packetArray, packetArray.length); while (true) {
multicastSocket.receive(packet); multicastSocket.receive(packet);
count++; count++;
ByteArrayInputStream bais = new ByteArrayInputStream(packet.getData()); nextChar = ' ';
DataInputStream dis = new DataInputStream(bais); while (nextChar != ';') // read and build string until terminator ; found
String firstCharacters = new String(); {
char nextChar = ' '; nextChar = buffer.getChar();
while (nextChar != ';') // read and build string until terminator ; found firstCharacters.append(nextChar);
{ }
nextChar = dis.readChar(); if (firstCharacters.toString().contains(MulticastSender.QUIT_SENTINEL)) {
firstCharacters += nextChar; System.out.println("Received sentinel \"" + MulticastSender.QUIT_SENTINEL + "\"");
} if (!INFINITE_READ_LOOP) {
if (firstCharacters.contains(MulticastSender.QUIT_SENTINEL))
{
System.out.println("Received sentinel \"" + MulticastSender.QUIT_SENTINEL + "\"");
if (!infiniteReadLoop)
break; // exit out of reading loop break; // exit out of reading loop
} }
int index = dis.readInt(); }
float firstFloat = dis.readFloat(); index = buffer.getInt();
float secondFloat = dis.readFloat(); firstFloat = buffer.getFloat();
secondFloat = buffer.getFloat();
if (count < 10) System.out.print(" "); // prettier output formatting buffer.clear();
if (count < 10) {
System.out.print(" "); // prettier output formatting
}
System.out.print(count + ". \"" + firstCharacters + "\" "); // wrap string in quote marks System.out.print(count + ". \"" + firstCharacters + "\" "); // wrap string in quote marks
System.out.println("index=" + index + ", firstFloat=" + firstFloat + " secondFloat=" + secondFloat); System.out.println("index=" + index + ", firstFloat=" + firstFloat + " secondFloat=" + secondFloat);
System.out.println("MulticastReceiver loop complete."); System.out.println("MulticastReceiver loop complete.");
firstCharacters.setLength(0);
} }
} } catch (IOException e) {
catch(IOException e) System.err.println("Problem with MulticastReceiver, see exception trace:");
System.err.println(e);
} finally // clean up after exit condition
{ {
System.out.println("Problem with MulticastReceiver, see exception trace:"); if (multicastSocket != null && !multicastSocket.isClosed()) {
System.out.println(e); try {
} multicastSocket.leaveGroup(group, ni);
finally // clean up after exit condition } catch (IOException ex) {
{ Logger.getLogger(MulticastReceiver.class.getName()).log(Level.SEVERE, null, ex);
// socket/database/completion cleanup code can go here, if needed. }
multicastSocket.close();
}
// socket/database/completion cleanup code can go here, if needed.
System.out.println("MulticastReceiver finally block, complete."); System.out.println("MulticastReceiver finally block, complete.");
} }
} }
} }
package UdpMulticastHttpExamples; package UdpMulticastHttpExamples;
import edu.nps.moves.dis7.utilities.DisThreadedNetIF;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
...@@ -28,9 +29,17 @@ public class MulticastSender { ...@@ -28,9 +29,17 @@ public class MulticastSender {
public static final String QUIT_SENTINEL = "QUIT QUIT QUIT!"; public static final String QUIT_SENTINEL = "QUIT QUIT QUIT!";
@SuppressWarnings("SleepWhileInLoop") @SuppressWarnings("SleepWhileInLoop")
public static void main(String[] args) public static void main(String[] args) throws IOException
{ {
MulticastSocket multicastSocket = null;
// Put together a message with binary content. "ByteArrayOutputStream"
// is a java.io utility that lets us put together an array of binary
// data, which we put into the UDP packet.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
try try
{ {
System.out.println("MulticastSender started..."); System.out.println("MulticastSender started...");
...@@ -42,53 +51,58 @@ public class MulticastSender { ...@@ -42,53 +51,58 @@ public class MulticastSender {
System.setProperty("java.net.preferIPv4Stack", "true"); System.setProperty("java.net.preferIPv4Stack", "true");
// multicast group we are sending to--not a single host // multicast group we are sending to--not a single host
MulticastSocket multicastSocket = new MulticastSocket(DESTINATION_PORT); multicastSocket = new MulticastSocket(DESTINATION_PORT);
multicastSocket.setTimeToLive(TTL); // time to live reduces scope of transmission multicastSocket.setTimeToLive(TTL); // time to live reduces scope of transmission
InetAddress multicastAddress = InetAddress.getByName(MULTICAST_ADDRESS); InetAddress multicastAddress = InetAddress.getByName(MULTICAST_ADDRESS);
System.out.println("Multicast address/port: " + multicastAddress.getHostAddress() + "/" + DESTINATION_PORT); System.out.println("Multicast address/port: " + multicastAddress.getHostAddress() + "/" + DESTINATION_PORT);
InetSocketAddress group = new InetSocketAddress(multicastAddress, DESTINATION_PORT);
// Join group useful on receiving side // Join group useful on receiving side
multicastSocket.joinGroup(multicastAddress); multicastSocket.joinGroup(group, DisThreadedNetIF.findIpv4Interface());
// You can join multiple groups here // You can join multiple groups here
DatagramPacket packet;
byte[] buffer;
for (int index = 0; index < LOOPSIZE; index++) for (int index = 0; index < LOOPSIZE; index++)
{ {
// Put together a message with binary content. "ByteArrayOutputStream" // Put together an updated packet to send
// is a java.io utility that lets us put together an array of binary if (index < LOOPSIZE - 1)
// data, which we put into the UDP packet. {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); // Put together an updated packet to send
DataOutputStream dos = new DataOutputStream(baos); dos.writeChars(System.getProperty("user.name") + ": ");
dos.writeChars("MulticastSender packet " + Integer.toString(index) + ";"); // string chars for readability
dos.writeInt (index); // arbitrary data, needs Java or byte-alignment to read
dos.writeFloat(17.0f); // arbitrary data, needs Java or byte-alignment to read
dos.writeFloat(23.0f); // arbitrary data, needs Java or byte-alignment to read
}
else dos.writeChars(QUIT_SENTINEL + ";"); // note string must include ; semicolon as termination sentinel
buffer = baos.toByteArray();
packet = new DatagramPacket(buffer, buffer.length, multicastAddress, DESTINATION_PORT);
// Put together an updated packet to send multicastSocket.send(packet);
if (index < LOOPSIZE - 1) System.out.println("Sent multicast packet " + index + " of " + LOOPSIZE);
{ baos.reset();
// Put together an updated packet to send
dos.writeChars(System.getProperty("user.name") + ": "); // How fast does this go? Does UDP try to slow it down, or does
dos.writeChars("MulticastSender packet " + Integer.toString(index) + ";"); // string chars for readability // this cause network problems? (hint: yes for an unlimited send
dos.writeInt (index); // arbitrary data, needs Java or byte-alignment to read // rate, unlike TCP). How do you know on the receiving side
dos.writeFloat(17.0f); // arbitrary data, needs Java or byte-alignment to read // that you haven't received a duplicate UDP packet, out of
dos.writeFloat(23.0f); // arbitrary data, needs Java or byte-alignment to read // order packet, or dropped packet? Necessary considerations.
} Thread.sleep(1000); // Send 100, one per second
else dos.writeChars(QUIT_SENTINEL + ";"); // note string must include ; semicolon as termination sentinel
byte[] buffer = baos.toByteArray();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, multicastAddress, DESTINATION_PORT);
multicastSocket.send(packet);
System.out.println("Sent multicast packet " + index + " of " + LOOPSIZE);
// How fast does this go? Does UDP try to slow it down, or does
// this cause network problems? (hint: yes for an unlimited send
// rate, unlike TCP). How do you know on the receiving side
// that you haven't received a duplicate UDP packet, out of
// order packet, or dropped packet? Necessary considerations.
Thread.sleep(1000); // Send 100, one per second
} }
System.out.println("MulticastSender complete."); System.out.println("MulticastSender complete.");
} }
catch(IOException | InterruptedException e) catch(IOException | InterruptedException e)
{ {
System.out.println("Problem with MulticastSender, see exception trace:"); if (multicastSocket != null)
System.out.println(e); multicastSocket.close();
dos.close();
System.err.println("Problem with MulticastSender, see exception trace:");
System.err.println(e);
} }
} }
......
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