首页 > > 详细

代做Computer Networks、辅导Java编程语言

Computer Networks
Stony Brook University
Fall 2023
Ping Server
Due: Sunday, October 8 at 11:59pm

Objectives
In this assignment, you will learn how to program a Ping Client/Server using UDP.
.
1.You can choose any programming IDE (or simple text editor) for writing your codes. NetBeans and Eclipse are some IDE choices for you.
2.The entire assignment must be done in Java.
3.See the end of this document for more instructions.

Rubrics: 40 pts

Problem Description: Read through the whole description before coding. 
In this assignment, we will study a simple Internet ping server written in the Java language and implement a corresponding client. The functionality provided by these programs are similar to the standard ping programs available in modern operating systems, except that they use UDP rather than Internet Control Message Protocol (ICMP) to communicate with each other. (Java does not provide a straightforward means to interact with ICMP.)
Ping is the primary command used to troubleshoot connectivity and reachability on a network. The ping protocol allows a client machine to send a packet of data to a remote machine, and have the remote machine return the data back to the client unchanged (an action referred to as echoing). Among other uses, the ping protocol allows hosts to determine round-trip times to other machines.
Using Ping
First, we will examine the existing Ping client on Windows. To do so, open a command prompt window.  You can find the command prompt by going to the start menu, and type “command” in the “search programs” box. Your window should look like the following:

 The Ping client on Windows is simply called ping. It is used in conjunction with a destination URL or IP address.  For example, type:
ping google.com
The following is a screenshot of a successful run of the ping client. 

The results show that four packets of 32 bytes each were sent to google.com, and four packets of 32 bytes each were returned from google.com (echoed).  The round-trip times are also shown.
Interestingly, one common use of ping is to determine whether a website is currently available. Of course, a website not responding to ping does not necessarily mean the web site is not available. To send a response, a web server must have a ping server running, and its ping messages must not be blocked by a firewall.
In the following parts, we will look at both the server side and the client side of ping.
Part 1: Ping Server in Java
In the following steps, we will go through the code for the first implementation of our Ping Server. Since we are building our server on top of UDP, this will be a UDP server. Wherever you see ". . . ", you will need to supply the missing details. 
The structure of the ping server is shown below: 
UDPServer.java

public class UDPServer {

public static void main(String args[]) throws Exception {
. . . . .
}
}
This is just the main function. Let’s start programming.
The standard ping uses the ICMP protocol, which is not port based. Since we are building a ping server based on UDP, we will need to specify a port.  The server will take a port number as an argument, so that each time you run the server, you can specify a different port number. This port number is the first argument, represented by args[0].
You may copy and paste the following code into your main function.
    
        int port = 0;
        
        /** Parse port number from command line **/
        try {
            port = . . . ;
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Need one argument: port number.");
            System.exit(-1);
        } catch (NumberFormatException e) {
            System.out.println("Please give port number as integer.");
            System.exit(-1);
        }
Next, we create a new socket using the DatagramSocket class.
        /** Create a new datagram socket at the port **/
        DatagramSocket serverSocket = . . . ;

        . . . .

        /** Let the user know the server is running **/
        System.out.println("The UDP server is listening on port " + port);
Next, we wait for a new UDP packet. UDP does not require a connection, so we are not waiting for a connection request. Because we will be servicing messages indefinitely, we place the listen operation inside of an infinite loop. This means we will have to terminate the UDP server by pressing Ctrl+C on the keyboard.
        while (true) {
            
           /** Create a new datagram packet and let the socket receive it **/
……..
            
            /** Print the message received **/
            ………..
            
            /** Get the IP Address of the Sender **/
            
            ……..
            /** Get the port of the Sender **/
            int senderPort = . . . ;
            
            /** Prepare the data to send back **/
. . . . .             
            /** Send the packet **/
            . . . . .
            
        }

This completes the UDP ping server. Remember what ping does: it sends the exact data it received back to the sender. That is what sendData should be.

Testing Your Server
Like we said in the beginning, the server will take a port number as a single argument when run, so that each time you run the server, you need to specify a port number.  Let’s use port 8000 as an example.
To run a Java program in NetBeans with an argument, you may have to download and install the “Run with Arguments” plug-in: http://plugins.netbeans.org/plugin/53855/run-with-arguments 
To run a Java program with an argument under the command prompt, you type the argument after the name of the program:  java UDPServer 8000

This runs the UDP server listening on port 8000.
You have no way of independently testing the UDP server response yet, since you don’t have a client that sends the message. Complete testing will be done after Part 2.
Part 2: Ping Client in Java
There are three files to work with here:
Message.java
PingClient.java
UDPClient.java

The Message class is the class for a ping message. This file is complete and is given to you. A ping message contains three pieces of information, the IP address, and port, and the message data itself.

The PingClient class provides the functionality of creating a socket and sending/receiving ping messages. Let’s work on this.

    /** Socket which we use. */
    DatagramSocket socket;

    /** Set maximum length of a ping message to 512. */
. . . . .
We will make two createSocket functions, one using any available port and one using a specified port number.

    /** Create a datagram socket with random port for sending UDP messages */
    public void createSocket() {
try {
    socket = . . . ;
} catch (SocketException e) {
    System.out.println("Error creating socket: " + e);
}
    }

    /** Create a datagram socket for receiving UDP messages. 
     * This socket must be bound to the given port. */
    public void createSocket(int port) {
try {
    socket = . . . ;
} catch (SocketException e) {
    System.out.println("Error creating socket: " + e);
}
    }

The next function sends a ping message, using the Message class provided.

    /** Send a UDP ping message which is given as the argument. */
    public void sendPing(Message ping) {
        
.. . . . . .

try {
    /* Create a datagram packet addressed to the recipient */
    . . .
    
    /* Send the packet */
    . . . . . .
    System.out.println("Sent message to " + host + ":" + port);
} catch (IOException e) {
    System.out.println("Error sending packet: " + e);
}
    }

The last function receives a ping message, using the Message class provided.

    /** Receive a UDP ping message and return the received message. 
     * We throw an exception to indicate that the socket timed out. 
     * This can happen when a message is lost in the network. */
    

public Message receivePing() throws SocketTimeoutException {

        /* Create packet for receiving the reply */
. . . . . .

/* Read message from socket. */
try {
    . . . . .
    
} catch (SocketTimeoutException e) {
    throw e;
} catch (IOException e) {
    System.out.println("Error reading from socket: " + e);
}
return reply;
    }

Because the socket has a timeout, we may get a SocketTimeoutException. The calling function needs to know of this timeout to know when to quit. However, SocketTimeoutException is a subclass of IOException which signals read errors on the socket, so we need to catch SocketTimeoutException here and throw it forward.

This completes the code for the second class of the ping client. All that is left is the UDP Client itself.

Now let’s work on the UDPClient class.  The UDPClient extends PingClient and inherits all its functions. We will start with a bunch of set-up variables.

    /** Host to ping */
    String remoteHost;
    
    /** Port number of remote host */
    int remotePort;

    /** How many pings to send */
    static final int NUM_PINGS = 10;
    
    /** How many reply pings have we received */
    int numReplies = 0;
    
    /** Crate an array for holding replies and RTTs */
     . . . . . . .

    /* Send our own pings at least once per second. If no replies received
     within 5 seconds, assume ping was lost. */
    /** 1 second timeout for waiting replies */
    static final int TIMEOUT = 1000;
    
    /** 5 second timeout for collecting pings at the end */
    static final int REPLY_TIMEOUT = 5000;

We create the constructor for this class, using the variables above.


    /** constructor **/
    public UDPClient(String host, int port) {
        . . . 
    }

Next, we create the main function for this class. This is where we run the client.

    /**
     * Main function. Read command line arguments and start the client.
     */
public static void main(String args[]) {

        String host = null;
        int port = 0;
The client runs with two arguments, a destination server address, and a destination port number. The destination server (host) address is the first argument, represented by args[0], and the port number is the second argument, represented by args[1].
        /* Parse host and port number from command line */
        try {
. . .
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Need two arguments: remoteHost remotePort");
            System.exit(-1);
        } catch (NumberFormatException e) {
            System.out.println("Please give port number as integer.");
            System.exit(-1);
        }

        System.out.println("Contacting host " + host + " at port " + port);

       . . . . .
    }

Here we have created a new UDPClient object, and called the run() function of this new object.  The main() function is finished. Let’s create the run() function next.

    public void run() {
    
        /* Create socket. We do not care which local port we use. */
. . . . .
        try {
            socket.setSoTimeout(TIMEOUT);
        } catch (SocketException e) {
            System.out.println("Error setting timeout TIMEOUT: " + e);
        }

        for (int i = 0; i < NUM_PINGS; i++) {

            /* Message we want to send to server is just the current time. */
. . . . .
            

            /* Send ping to recipient */
            try {
                ping = new Message(. . . .);

            } catch (UnknownHostException e) {
                System.out.println("Cannot find host: " + e);
            }
. . . . .
            /* Read the reply by getting the received ping message */
            try {
                Message reply = . . . ;
                 . . . . .
            } catch (SocketTimeoutException e) {
                /* Reply did not arrive. Do nothing for now. Figure
                 * out lost pings later. */
            }
        }

This is the end of the for() loop. Other than the handleReply() function above, we just need to tidy up some loose ends, and print out some statistics.

We sent all our pings. Now check if there are still missing replies. Wait for a reply, if nothing comes, then assume it was lost. If a reply arrives, keep looking until nothing comes within a reasonable timeout.

        try {
            socket.setSoTimeout(REPLY_TIMEOUT);
        } catch (SocketException e) {
            System.out.println("Error setting timeout REPLY_TIMEOUT: " + e);
        }
        while (numReplies < NUM_PINGS) {
            try {
                Message reply = . . . ;
                 . . . . .
            } catch (SocketTimeoutException e) {
                /* Nothing coming our way apparently. Exit loop. */
                 . . . . . . .
            }
        }
        /* Print statistics */
        for (int i = 0; i < NUM_PINGS; i++) {
            . . . . . .
        }

    }

This completes the run() function.

Lastly, there is just the handleReply() function.  This function processes the reply string and get the relevant information.

    private void handleReply(String reply) {
. . . . .
}    

Remember that the message we sent to the server was the time at that moment. The server has echoed that message back to us. Here we have parsed the message that was echoed back to us and got the old time.  How do you calculate the Round-Trip Time?

        /* Calculate RTT and store it in the rtt-array. */
         . . .

        numReplies++;
    }

This is it. You have completed all the functions.

A final note on servers: typically speaking, when we say the word “server”, we meant a server that serves webpages: an HTTP server (unless you are in a restaurant…), but a server really can serve a lot of different protocols. In this assignment, you have created a Ping Server.  You can also create servers for FTP, SMTP, etc.  You would run them separately on the same machine (the “server” machine), at the same time, to provide the different functions. They do not interfere with one another, as long as each of them uses a different port number. This is how a server machine would take care of a combination of requests.  
Testing Your Client and Server
Now that you have a client and a server ready to go, we can fully test both sides. First, ensure that your client can start properly. Remember that the client must take two arguments, the destination server address, and the destination port number.

Since you will be testing this with your client and server residing on the same local machine, your server address is 127.0.0.1 or localhost.

Let’s use 8000 as our example port number. Your two arguments will be localhost 8000.

If you are running this from the command prompt, then you will type in:

java UDPClient localhost 8000

If you are using NetBeans, again you may need to get the plug-in.

Once you see these messages popping up, then your client is sending messages.

Now run the server. Once the server is listening, run the client again. Make sure they are using the same port number.

The server side:

The client side:

Rubrics:
1.Please follow the instructions in the previous pages. Your client and server code will be separately tested against a different client and server, with an arbitrary port number. To receive any credit, your Java code must compile.
2.Correctness (including formatting):
1.Part 1 implemented correctly: Your UDP server is correctly showing the content of incoming ping messages on the screen (10 points).
2.Part 2 implemented correctly: Your UDP client is sending the correct ping messages to the ping server. (10 points)
3.Part 2 implemented correctly: Your UDP client is correctly showing the reply from the ping server (10 points)
4.Part 2 implemented correctly: Your UDP client is correctly showing RTT of the message to/from the ping server (10 points)
Total: 40 points

Submission:
Please zip your code (all parts) and all the necessary resources to test your program in one Zip file and submit the file on Brightspace. Late assignments are not accepted.

联系我们
  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp
热点标签

联系我们 - QQ: 99515681 微信:codinghelp
程序辅导网!