Skip to content
Snippets Groups Projects
UnicastUdpSender.java 7.09 KiB
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
        }
    }
}