From d2ac0bc43718328bd3f228cde7bb87d3d2c4731b Mon Sep 17 00:00:00 2001 From: johns <johns@192.168.2.9> Date: Mon, 1 May 2023 11:41:27 -0700 Subject: [PATCH] Initial Commit --- .../Fredrickson/UnicastUdpReceiver.java | 114 ++++++++++++++ .../Fredrickson/UnicastUdpSender.java | 143 ++++++++++++++++++ 2 files changed, 257 insertions(+) create mode 100644 assignments/src/MV3500Cohort2023MarchJune/homework2/Fredrickson/UnicastUdpReceiver.java create mode 100644 assignments/src/MV3500Cohort2023MarchJune/homework2/Fredrickson/UnicastUdpSender.java diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework2/Fredrickson/UnicastUdpReceiver.java b/assignments/src/MV3500Cohort2023MarchJune/homework2/Fredrickson/UnicastUdpReceiver.java new file mode 100644 index 0000000000..991ef8cf06 --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/homework2/Fredrickson/UnicastUdpReceiver.java @@ -0,0 +1,114 @@ +package MV3500Cohort2023MarchJune.homework2.Fredrickson; + +import java.io.*; +import java.net.*; + +/** + * An example of receiving UDP packets. Since very often both the + * sender and receiver are on the same host we use different ports + * for each. This prevents collision complaints from the localhost. + * + * Start this before launching UdpSender. + * + * @see <a href="https://docs.oracle.com/javase/tutorial/networking/datagrams/index.html">https://docs.oracle.com/javase/tutorial/networking/datagrams/index.html</a> + * @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> + * @author mcgredo + * @author brutzman@nps.edu + * + * (JOHN FREDRICKSON) I have made the following changes to this code: + * -changed output formatting + * + */ +public class UnicastUdpReceiver +{ + /** Default constructor */ + public UnicastUdpReceiver() + { + // default constructor + } +// public static final int SENDING_PORT = 1414; // port used by UdpSender, unneeded here + /** socket value of shared interest */ + public static final int UDP_PORT = 1415; // sharable + /** socket value of shared interest */ + public static final String DESTINATION_HOST = "localhost"; + + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String[] args) + { + DatagramSocket udpSocket = null; + + try + { + System.out.println(UnicastUdpReceiver.class.getName() + " started..."); + + // Create a UDP socket + udpSocket = new DatagramSocket(UDP_PORT); + udpSocket.setReceiveBufferSize(1500); // how many bytes are in buffer? MTU=1500 is good + udpSocket.setBroadcast(false); // we're just receiving here +// udpSocket.setReuseAddress(true); + + byte[] byteArray = new byte[1500]; + DatagramPacket receivePacket = new DatagramPacket(byteArray, byteArray.length); + + ByteArrayInputStream bais = new ByteArrayInputStream(byteArray); + DataInputStream dis = new DataInputStream(bais); + + boolean isEvenParity; + int packetCount = 0; + int firstInt; + float secondFloat; + String thirdString; + String padding; + + // You need a new receiving packet to read from every packet received + while (true) + { + packetCount++; // good practice to increment counter at start of loop, when possible + udpSocket.receive(receivePacket); // blocks until packet is received + + if (packetCount == 1) + { + if (udpSocket.getInetAddress() == null) + System.out.println("UdpReceiver address/port: UDP socket address null (loopback)" + "/" + UDP_PORT); + else System.out.println("UdpReceiver address/port: " + udpSocket.getInetAddress().getHostAddress() + "/" + UDP_PORT); + } + + // values of interest follow. order and types of what was sent must match what you are reading! + firstInt = dis.readInt(); // packetID + secondFloat = dis.readFloat(); + thirdString = dis.readUTF(); // string value with guaranteed encoding, matches UTF-8 is 8 bit + isEvenParity = dis.readBoolean(); // ok, we've gotten everything we're looking for. + + dis.reset(); // now clear the input stream after reading, in preparation for next loop + + if (isEvenParity) + padding = " "; + else padding = ""; + + System.out.println("[" + UnicastUdpReceiver.class.getName() + "]" + + " port=" + UDP_PORT + + " packetID=" + firstInt + // have output message use same name as sender + ", second float value=" + secondFloat + + ", third String value=\"" + thirdString + "\"" + // note that /" is literal quote character + " isPacketIdEvenParity=" + isEvenParity + "," + padding + + " packet counter=" + packetCount); + System.out.println(); + } + } + catch(IOException e) + { + System.err.println("Problem with UdpReceiver, see exception trace:"); + System.err.println(e); + } + finally // clean up prior to exit, don't want to leave behind zombie socket + { + if (udpSocket != null) + udpSocket.close(); + System.out.println(UnicastUdpReceiver.class.getName() + " complete."); // all done + } + } +} diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework2/Fredrickson/UnicastUdpSender.java b/assignments/src/MV3500Cohort2023MarchJune/homework2/Fredrickson/UnicastUdpSender.java new file mode 100644 index 0000000000..7863285a7a --- /dev/null +++ b/assignments/src/MV3500Cohort2023MarchJune/homework2/Fredrickson/UnicastUdpSender.java @@ -0,0 +1,143 @@ +package MV3500Cohort2023MarchJune.homework2.Fredrickson; + +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 + * + * + * (JOHN FREDRICKSON) I have made the following changes to this code: + * -changed output formatting + * + */ +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 = 100; + + /** 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 countdown = -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 + countdown = TOTAL_PACKETS_TO_SEND - packetID; // countdown from goal total + 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 (countdown); + dos.writeUTF (message); // string value with guaranteed encoding, matches UTF-8 is 8 bit + dos.writeBoolean(isPacketIdEvenParity); + + dos.flush(); // sends DataOutputStream to ByteArrayOutputStream, clearing the buffer + 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 = " "; // single blank character as a string of length 1 + else padding = ""; // empty string + + Thread.sleep(100); // Send packets at rate of one per second + System.out.println("[" + UnicastUdpSender.class.getName() + "] " + MY_NAME + " " + sourceAddress + + " port=" + UDP_PORT + + " has sent values (" + packetID + "," + countdown + ",\"" + message + "\"," + isPacketIdEvenParity + + ")" + padding + " as packet #" + index + " of " + TOTAL_PACKETS_TO_SEND); + System.out.println(); + 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