From b1c8e3eb40dcca73efe2bd2e9700e936b07c3513 Mon Sep 17 00:00:00 2001
From: thomascecil <thomascecil@thomass-air.ern.nps.edu>
Date: Wed, 26 Apr 2023 11:30:45 -0700
Subject: [PATCH] HW initial commit - Files in work

---
 .../Cecil/MulticastUdpReceiverCecil.java      | 123 ++++++++++++++++
 .../Cecil/MulticastUdpSenderCecil.java        | 134 ++++++++++++++++++
 2 files changed, 257 insertions(+)
 create mode 100644 assignments/src/MV3500Cohort2023MarchJune/homework2/Cecil/MulticastUdpReceiverCecil.java
 create mode 100644 assignments/src/MV3500Cohort2023MarchJune/homework2/Cecil/MulticastUdpSenderCecil.java

diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework2/Cecil/MulticastUdpReceiverCecil.java b/assignments/src/MV3500Cohort2023MarchJune/homework2/Cecil/MulticastUdpReceiverCecil.java
new file mode 100644
index 0000000000..6de9542685
--- /dev/null
+++ b/assignments/src/MV3500Cohort2023MarchJune/homework2/Cecil/MulticastUdpReceiverCecil.java
@@ -0,0 +1,123 @@
+package MV3500Cohort2023MarchJune.homework2.Cecil;
+
+import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface;
+import java.io.*;
+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.
+ *
+ * @author mcgredo
+ * @author brutzman@nps.edu
+ */
+public class MulticastUdpReceiverCecil
+{
+    /** Default constructor */
+    public MulticastUdpReceiverCecil()
+    {
+        // default constructor
+    }
+    // reserved range for all IPv4 multicast: 224.0.0.0 through 239.255.255.255
+    // https://en.wikipedia.org/wiki/Multicast_address
+    // https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
+    private static final String MULTICAST_ADDRESS = "239.1.2.15";
+    private static final int     DESTINATION_PORT = 1718;
+
+    /**
+     * Time to live: how many router-decrement levels can be crossed
+     */
+    private static final int TTL = 10;
+
+    private static final boolean INFINITE_READ_LOOP = true;
+    private static NetworkInterface ni;
+
+    /**
+     * Program invocation, execution starts here
+     * @param args command-line arguments
+     */
+    public static void main(String[] args)
+    {
+        MulticastSocket multicastSocket = null;
+        InetSocketAddress group = null;
+        ByteBuffer buffer = ByteBuffer.allocate(1500);
+        DatagramPacket packet = new DatagramPacket(buffer.array(), buffer.capacity());
+        
+        try {
+            System.out.println("UdpExamples.MulticastUdpReceiver started...");
+
+            // This is a java/IPv6 problem. You should also add it to the
+            // arguments used to start the app, eg -Djava.net.preferIPv4Stack=true
+            // set in the "run" section of preferences. Also, typically
+            // netbeans must be restarted after these settings.
+            // https://stackoverflow.com/questions/18747134/getting-cant-assign-requested-address-java-net-socketexception-using-ehcache
+            System.setProperty("java.net.preferIPv4Stack", "true");
+
+            multicastSocket = new MulticastSocket(DESTINATION_PORT);
+            multicastSocket.setTimeToLive(TTL);
+            InetAddress multicastAddress = InetAddress.getByName(MULTICAST_ADDRESS);
+            
+            group = new InetSocketAddress(multicastAddress, DESTINATION_PORT);
+            
+            // Join group useful on receiving side
+            multicastSocket.joinGroup(group, ni = DisThreadedNetworkInterface.findIpv4Interface());
+            // You can join multiple groups here
+            
+            System.out.println("Multicast address/port: " + multicastAddress.getHostAddress() + "/" + DESTINATION_PORT);
+            System.out.println("Multicast packets received log:");
+
+            int index, count = 0; // initialize
+            float firstFloat, secondFloat;
+            StringBuilder firstCharacters = new StringBuilder();
+            char nextChar;
+
+            while (true) { // true is always true, so this is an infinite loop that continues until interrupted
+                multicastSocket.receive(packet);
+                count++;
+
+                nextChar = ' ';
+                while (nextChar != ';') // read and build string until terminator ; found
+                {
+                    nextChar = buffer.getChar();
+                    firstCharacters.append(nextChar);
+                }
+                if (firstCharacters.toString().contains(MulticastUdpSenderCecil.QUIT_SENTINEL)) {
+                    System.out.println("Received sentinel \"" + MulticastUdpSenderCecil.QUIT_SENTINEL + "\"");
+                    if (!INFINITE_READ_LOOP) {
+                        break; // exit out of reading loop
+                    }
+                }
+                index = buffer.getInt();
+                firstFloat = buffer.getFloat();
+                secondFloat = buffer.getFloat();
+                buffer.clear();
+
+                if (count < 10) {
+                    System.out.print(" "); // prettier output formatting
+                }
+                System.out.print(count + ". \"" + firstCharacters + "\" "); // wrap string in quote marks
+                System.out.println("index=" + index + ", firstFloat=" + firstFloat + " secondFloat=" + secondFloat);
+
+                System.out.println("MulticastReceiver loop complete.");
+                firstCharacters.setLength(0);
+            }
+        } catch (IOException e) {
+            System.err.println("Problem with MulticastReceiver, see exception trace:");
+            System.err.println(e);
+        } finally // clean up after exit condition
+        {
+            if (multicastSocket != null && !multicastSocket.isClosed()) {
+                try {
+                    multicastSocket.leaveGroup(group, ni);
+                } catch (IOException ex) {
+                    Logger.getLogger(MulticastUdpReceiverCecil.class.getName()).log(Level.SEVERE, null, ex);
+                }
+                multicastSocket.close();
+            }
+            // socket/database/completion cleanup code can go here, if needed.
+            System.out.println("MulticastReceiver finally block, complete.");
+        }
+    }
+}
diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework2/Cecil/MulticastUdpSenderCecil.java b/assignments/src/MV3500Cohort2023MarchJune/homework2/Cecil/MulticastUdpSenderCecil.java
new file mode 100644
index 0000000000..37574e1038
--- /dev/null
+++ b/assignments/src/MV3500Cohort2023MarchJune/homework2/Cecil/MulticastUdpSenderCecil.java
@@ -0,0 +1,134 @@
+package MV3500Cohort2023MarchJune.homework2.Cecil;
+
+import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface;
+import java.io.*;
+import java.net.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Looks a lot like UdpSender.  Start this after launching MulticastReceiver.
+ * 
+ * Privacy note: this sender advertises your user name as part of the multicast packet message
+ * 
+ * @author mcgredo
+ * @author brutzman@nps.edu
+ */
+public class MulticastUdpSenderCecil
+{
+    /** Default constructor */
+    public MulticastUdpSenderCecil()
+    {
+        // default constructor
+    }
+    // reserved range for all IPv4 multicast: 224.0.0.0 through 239.255.255.255
+    // https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
+
+    /** Default multicast group address for send and receive connections.
+     * @see <a href="https://en.wikipedia.org/wiki/Multicast_address">https://en.wikipedia.org/wiki/Multicast_address</a> */
+    public static final String MULTICAST_ADDRESS = "239.1.2.15"; // within reserved multicast address range
+    /** Default socket 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> */
+    public static final int     DESTINATION_PORT = 1718;
+    
+    /** Time to live: how many router-decrement levels can be crossed */
+    public static final int TTL = 10;
+	
+    /** How many packets to send prior to termination */
+    public static final int LOOPSIZE = 20; // or maybe 20000
+    
+    /** Receiving this message causes termination
+     * @see <a href="https://en.wikipedia.org/wiki/Sentinel_value">https://en.wikipedia.org/wiki/Sentinel_value</a> */
+    public static final String QUIT_SENTINEL = "QUIT QUIT QUIT!";
+    private static NetworkInterface ni;
+    
+    /**
+     * Program invocation, execution starts here
+     * @param args command-line arguments
+     * @throws java.io.IOException execution error
+     */
+    @SuppressWarnings("SleepWhileInLoop")
+    public static void main(String[] args) throws IOException 
+    {
+        MulticastSocket multicastSocket = null;
+        InetSocketAddress group = 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
+        {
+            System.out.println("UdpExamples.MulticastUdpSender started...");
+            // This is a java/IPv6 problem. You should also add it to the
+            // arguments used to start the app, eg -Djava.net.preferIPv4Stack=true
+            // set in the "run" section of preferences. Also, typically
+            // netbeans must be restarted after these settings.
+            // https://stackoverflow.com/questions/18747134/getting-cant-assign-requested-address-java-net-socketexception-using-ehcache
+            System.setProperty("java.net.preferIPv4Stack", "true");
+            
+            // multicast group we are sending to--not a single host
+            multicastSocket = new MulticastSocket(/*DESTINATION_PORT*/);
+            multicastSocket.setTimeToLive(TTL); // time to live reduces scope of transmission
+            InetAddress multicastAddress = InetAddress.getByName(MULTICAST_ADDRESS);
+            System.out.println("Multicast address/port: " + multicastAddress.getHostAddress() + "/" + DESTINATION_PORT);
+            
+            group = new InetSocketAddress(multicastAddress, DESTINATION_PORT);
+            // Join group useful on receiving side
+            multicastSocket.joinGroup(group, ni = DisThreadedNetworkInterface.findIpv4Interface());
+            // You can join multiple groups here
+            
+            byte[] buffer = baos.toByteArray();
+            DatagramPacket packet = new DatagramPacket(buffer, buffer.length, group/*, DESTINATION_PORT*/);
+            
+            for (int index = 0; index < LOOPSIZE; index++)
+            {
+                // Put together an updated packet to send
+                if (index < LOOPSIZE - 1)
+                {
+                    // Put together an updated packet to send
+                    dos.writeChars("From " + 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.setData(buffer);
+                multicastSocket.send(packet);
+                System.out.println("Sent multicast packet " + (index + 1) + " of " + LOOPSIZE);
+                baos.reset();
+
+                // 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.");
+        }
+        catch(IOException | InterruptedException e)
+        {
+            System.err.println("Problem with MulticastSender, see exception trace:");
+            System.err.println(e);
+        } finally {
+            
+            if (multicastSocket != null && !multicastSocket.isClosed()) {
+                try {
+                    multicastSocket.leaveGroup(group, ni);
+                } catch (IOException ex) {
+                    Logger.getLogger(MulticastUdpSenderCecil.class.getName()).log(Level.SEVERE, null, ex);
+                }
+                multicastSocket.close();
+            }
+            
+            dos.close();
+        }
+    }
+    
+}
-- 
GitLab