From 75d96a318905629c9a5cb557c4fd4f430bb45f29 Mon Sep 17 00:00:00 2001
From: "Islas, Sean (Capt)" <sean.islas@nps.edu>
Date: Mon, 1 May 2023 10:56:42 -0700
Subject: [PATCH] Add new file

---
 .../homework2/Islas/UnicastUdpSender.java     | 138 ++++++++++++++++++
 1 file changed, 138 insertions(+)
 create mode 100644 assignments/src/MV3500Cohort2023MarchJune/homework2/Islas/UnicastUdpSender.java

diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework2/Islas/UnicastUdpSender.java b/assignments/src/MV3500Cohort2023MarchJune/homework2/Islas/UnicastUdpSender.java
new file mode 100644
index 0000000000..c5f10beed4
--- /dev/null
+++ b/assignments/src/MV3500Cohort2023MarchJune/homework2/Islas/UnicastUdpSender.java
@@ -0,0 +1,138 @@
+package MV3500Cohort2023MarchJune.homework2.Islas;
+
+import java.io.*;
+import java.net.*;
+
+/**
+ * An example of sending UDP packets. The sending and receiving programs
+ * use different UDP ports; there can be problems getting this to work
+ * if both the sending and receiving sockets try to use the same port
+ * on the same host.
+ * 
+ * Start this before launching UdpReceiver.
+ * 
+ * @see <a href="https://docs.oracle.com/javase/tutorial/essential/io/datastreams.html">https://docs.oracle.com/javase/tutorial/essential/io/datastreams.html</a>
+ * @see <a href="https://en.wikipedia.org/wiki/User_Datagram_Protocol">https://en.wikipedia.org/wiki/User_Datagram_Protocol</a>
+ * @see <a href="https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html">System properties</a>
+ * @author mcgredo
+ * @author brutzman@nps.edu
+ */
+public class UnicastUdpSender 
+{
+    /** Default constructor */
+    public UnicastUdpSender()
+    {
+        // default constructor
+    }
+    private static final String            MY_NAME = System.getProperty("user.name"); // guru incantation   8)
+//  public  static final int          SENDING_PORT = 1414; // not needed, can let system choose an open local port
+    /** socket value of shared interest */
+    public  static final int              UDP_PORT = UnicastUdpReceiver.UDP_PORT; // 1415; ensure consistent
+    private static final int TOTAL_PACKETS_TO_SEND = 25;
+    
+    /** socket value of shared interest */
+    public static  final String   DESTINATION_HOST = "localhost"; 
+    // here is what we need for lab comms
+//  public static final String   DESTINATION_HOST = "10.1.105.16"; // localhost 127.0.0.1 or argon 10.1.105.1 or 10.1.105.1 or whatever
+    
+    /**
+     * Program invocation, execution starts here
+     * @param args command-line arguments
+     */
+    @SuppressWarnings("SleepWhileInLoop")
+    public static void main(String[] args)
+    {
+        DatagramSocket udpSocket = null;
+        DataOutputStream  dos = null;
+        int   packetID = 0;     // counter variable to send in packet
+        float    value = -1.0f; // unreachable value is good sentinel to ensure expected changes occur
+        String message = MY_NAME + " says Hello MV3500"; // no really
+        // String padding = new String();
+        
+        try
+        {
+            System.out.println(UnicastUdpSender.class.getName() + " shows how to send simple-type values via DataOutputStream");
+            System.out.println(UnicastUdpSender.class.getName() + " started...");
+            
+            // Create a UDP socket
+            udpSocket = new DatagramSocket(); // let system assign output port, then SENDING_PORT not needed
+            
+            // 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(1500); // how many bytes are in buffer?  MTU=1500 is good
+            dos = new DataOutputStream(baos); // wrapper for writing values, connects both streams
+			
+            // Put together a packet to send
+            // these types and order of variables must match on sender and receiver
+            byte[] byteArray = baos.toByteArray();
+            
+            // ID of the host we are sending to
+            InetAddress destinationAddress = InetAddress.getByName(DESTINATION_HOST);
+            // ID of the host we are sending from
+            // InetAddress      sourceAddress = InetAddress.getByName("localhost"); // possibly identical if source not modified
+            
+            DatagramPacket datagramPacket = new DatagramPacket(byteArray, byteArray.length, destinationAddress, UDP_PORT);
+            
+            System.out.println("UdpSender address/port: " + destinationAddress.getHostAddress() + "/" + UDP_PORT);
+       
+            // Hmmm, how fast does UDP stream go? Does UDP effectively slow packets 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? your responsibility.
+            
+            for (int index = 1; index <= TOTAL_PACKETS_TO_SEND; index++) // avoid infinite send loops in code, they can be hard to kill!
+            {
+                packetID++;                               // increment counter, prefer using explicit value to index
+                value = TOTAL_PACKETS_TO_SEND - packetID; // countdown
+                boolean isPacketIdEvenParity = ((packetID % 2) == 0); // % is modulo operator; result 0 is even parity, 1 is odd parity
+                
+                // values of interest follow. order and types of what was sent must match what you are reading!
+                dos.writeInt    (packetID);
+                dos.writeFloat  (value);
+                dos.writeUTF    (message); // string value with guaranteed encoding, matches UTF-8 is 8 bit
+                dos.writeBoolean(isPacketIdEvenParity);
+                
+                dos.flush(); // sends DataOutputStream to ByteArrayOutputStream
+                byteArray = baos.toByteArray();    // OK so go get the flushed result...
+                datagramPacket.setData(byteArray); // and put it in the packet...
+                udpSocket.send(datagramPacket);    // and send it away. boom gone, nonblocking.
+//              System.out.println("udpSocket output port=" + udpSocket.getLocalPort()); // diagnostic tells what port was chosen by system
+                
+                // if  (isPacketIdEvenParity)
+                //      padding = " ";
+                // else padding = "";
+            
+                Thread.sleep(100); // Send packets at rate of one per second
+                System.out.println(" My guess is: " + packetID + "m/s");
+                // System.out.println("[" + UnicastUdpSender.class.getName() + "] " + MY_NAME + " " + sourceAddress +
+                //                    " port=" + UDP_PORT +
+                //                    " has sent values (" + packetID + "," + value + ",\"" + message + "\"," + isPacketIdEvenParity +
+                //                    ")" + padding + " as packet #" + index + " of " + TOTAL_PACKETS_TO_SEND);
+                baos.reset(); // clear the output stream after sending
+            }   // end for loop
+        }
+        catch (IOException | InterruptedException e)
+        {
+            System.err.println("Problem with UdpSender, see exception trace:");
+            System.err.println(e);
+        } 
+        finally // clean up prior to exit, don't want to leave behind zombies
+        {
+            if (udpSocket != null)
+                udpSocket.close();
+            try
+            {
+                if (dos != null)
+                    dos.close();
+            }
+            catch (IOException e)
+            {
+                System.err.println("Problem with UdpSender, see exception trace:");
+                System.err.println(e);
+            } 
+            System.out.println(UnicastUdpSender.class.getName() + " complete."); // all done
+        }
+    }
+}
-- 
GitLab