CSE 473 – Introduction to Computer Networks Lab 1 Solution Jon Turner Part A (15 points). Paste a copy of the source code for MapServer.java here. Use the “code” paragraph style and make sure that none of the lines wraps around. Don’t forget to include appropriate comments in your code. /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Simple MapServer that stores (key,value) strings. usage: MapServer [ portNumber ] There is a single optional command line argument that is the port number of the port that the server listens on. The port number defaults to 30123. The server expects to receive UDP packets that store and retrieve (key,value) pairs, where both the key and the value are strings. There are two commands, get and put. Get takes a single argument (the key) and put can take either one or two arguments (key,value). If only the key is provided, the mapping for that key is removed. If both key and value are provided, a new mapping is created, possibly replacing an existing pair. The packets contain contain ASCII strings separated by ":" characters. For example, to perform the operation put("foo","bar"), the remote client would send a packet containing the characters put:foo:bar To perform the operation get("who hah") the client would send a packet containing get:who hah The reply to a successful put is a packet containing the characters ok The reply to a succesful get is ok:result string where "result string" is the stored value. If the key to a get does not match any stored value, the server returns no match On an error, the server returns error:error message -1- */ import java.io.*; import java.net.*; import java.util.*; public class MapServer { public static void main(String args[]) throws Exception { // open datagram socket and bind to specified port of 30123 int port = 30123; if (args.length > 0) port = Integer.parseInt(args[0]); DatagramSocket sock = new DatagramSocket(port); byte[] buf = new byte[2000]; DatagramPacket pkt = new DatagramPacket(buf, buf.length); HashMap<String,String> map = new HashMap<String,String>(); while (true) { // wait for message to arrive pkt.setData(buf); sock.receive(pkt); String message = new String(buf,0,pkt.getLength(), "US-ASCII"); String reply; // split string contained in packet into substrings and // respond appropriately String[] chunks = message.split(":",2); if (chunks.length != 2) { reply = "error:unrecognizable input:" + message; } else { if (chunks[0].equals("get")) { String val = map.get(chunks[1]); if (val != null) reply = "ok:" + val; else reply = "no match"; } else if (chunks[0].equals("put")) { String[] parts = chunks[1].split(":",2); if (parts.length == 2) map.put(parts[0],parts[1]); else map.remove(parts[0]); reply = "ok"; } else { reply = "error:unrecognizable input:" + message; } } // send reply pkt.setData(reply.getBytes("US-ASCII")); sock.send(pkt); } } } -2- Part B (15 points). Paste a copy of the source code for MapClient.java here. /** * * * * * * * * * * * * * * * */ Simple client for use with a MapServer that stores (key,value) strings. usage: MapClient serverName serverPort cmdName [ arg1 arg2 ] Send a command to a remote MapServer in a UDP datagram. Wait for reply packet and print its contents. The first argument is the domain of a remote host, the second is a port number used by a MapServer on that remote host. The cmdName is "get" or "put" and the optional arguments can be arbitrary strings. The client does no checking of the last three arguments, allowing malformed packets to be sent to the server. This allows us to verify that the server can detect malformed packets. import java.io.*; import java.net.*; import java.util.*; public class MapClient { public static void main(String args[]) throws Exception { // process command line arguments if (args.length < 3) { System.out.println("usage: MapClient serverName " + "serverPort cmdName [ arg1 arg2 ]"); System.exit(1); } InetAddress serverAdr = InetAddress.getByName(args[0]); int port = Integer.parseInt(args[1]); String message = args[2]; if (args.length > 3) message = message + ":" + args[3]; if (args.length > 4) message = message + ":" + args[4]; // send packet containing command to server DatagramSocket sock = new DatagramSocket(); byte[] buf = message.getBytes("US-ASCII"); DatagramPacket pkt = new DatagramPacket(buf, buf.length, serverAdr,port); sock.send(pkt); // and handle response buf = new byte[2000]; DatagramPacket reply = new DatagramPacket(buf, 2000); sock.receive(reply); System.out.println(new String(buf,0,buf.length,"US-ASCII")); sock.close(); } } -3- Part C (10 points). Paste a copy of the output from testScript when both client and server are run on the same computer. java MapClient localhost 30123 put foo bar ok java MapClient localhost 30123 put who hah ok java MapClient localhost 30123 put goodbye world ok java MapClient localhost 30123 get foo ok:bar java MapClient localhost 30123 get who ok:hah java MapClient localhost 30123 put who ok java MapClient localhost 30123 get who no match java MapClient localhost 30123 get goodbye ok:world java MapClient localhost 30123 got goodbye error:unrecognizable input:got:goodbye java MapClient localhost 30123 pat goodbye world error:unrecognizable input:pat:goodbye:world java MapClient localhost 30123 get bar no match java MapClient localhost 30123 put foo toast is tasty ok java MapClient localhost 30123 get foo ok:toast is tasty -4- Part D (10 points). Paste a copy of the output from testScript when the client and server are run on different computers. java MapClient forest2.arl.wustl.edu 30123 put ok java MapClient forest2.arl.wustl.edu 30123 put ok java MapClient forest2.arl.wustl.edu 30123 put ok java MapClient forest2.arl.wustl.edu 30123 get ok:bar java MapClient forest2.arl.wustl.edu 30123 get ok:hah java MapClient forest2.arl.wustl.edu 30123 put ok java MapClient forest2.arl.wustl.edu 30123 get no match java MapClient forest2.arl.wustl.edu 30123 get ok:world java MapClient forest2.arl.wustl.edu 30123 got error:unrecognizable input:got:goodbye java MapClient forest2.arl.wustl.edu 30123 pat error:unrecognizable input:pat:goodbye:world java MapClient forest2.arl.wustl.edu 30123 get no match java MapClient forest2.arl.wustl.edu 30123 put ok java MapClient forest2.arl.wustl.edu 30123 get ok:toast is tasty -5- foo bar who hah goodbye world foo who who who goodbye goodbye goodbye world bar foo toast is tasty foo Part E (10 points). Paste a screenshot of the Wireshark window at the client computer below, showing the packets transferred when you run testScript. Make sure that the top portion of the window shows all packets sent and received. Also select packet number 11, and in the middle portion of the window expand the sections for the User Datagram Protocol and for the Data part of the packet. Make sure that all text is clearly legible (you may need to adjust the size of the Wireshark window when you do the capture, to ensure that everything is legible in the report). -6- Paste a screenshot of the Wireshark window at the server computer below, showing the packets transferred when you run testScript. In this case select packet number 12, and again, make sure that all relevant data is visible. -7- Part F (10 points). Answer the following questions using the Wireshark output. 1. What is the IP address of the host on which the server runs? What is the IP address of the host on which the client runs? What are the Ethernet addresses of the two hosts? The server’s IP address is 128.252.153.21, the client’s is 172.16.8.210. The ethernet addresses are tricky to determine in this case, as the two hosts are in different Ethernet networks. The server’s address can be found in the wireshark window from the server. It is 00:06:5b:38:35:a7. Similarly, the client’s can be found in the wireshark window from the client. It is 40:6c:8f:3a:68:d6. 2. What port number is used by the client in your session when packet #11 is sent? Is this same port number used when the other packets are sent? Do you understand why? Port number 61864 is used by the client for packet 11. Other packets use different port numbers, since every line in the script involved a different invocation of the client program, and each invocation opens its own socket. 3. The bottom section of the Wireshark output shows the contents of the packet as a series of 8 bit hexadecimal values. Find the 4 hex digits that correspond to the client’s port number (hint, click on the port number in the middle section of the window) for packet number 11. What are these hex digits. Which hex digit is the most significant? Which is the least significant? Verify that the hex value represented by these 4 hex digits matches the number you observed. The four hex digits are f1 a8 and since the packet is shown in network byte order, the most significant digit is ‘f’ and the least significant is ‘8’. This hex value is equivalent to the decimal value 15*163 + 1*162 + 10*16 + 8 = 61440 + 256 + 160 + 8 = 61864 as expected. 4. How many bytes are shown in the window for packet number 11? How many of these bytes are associated with the actual get command? How many are associated with the UDP protocol? How many are associated with the IP protocol? What about the rest? There are 49 bytes in packet number 11. Of these, the string “put:who” accounts for 7, the UDP header accounts for 8, the IP header accounts for 20 and the remaining 14 come from the Ethernet header. 5. At what time (according to Wireshark) did the server receive packet 11? At what time did it send the reply? What is the difference between these two times? When did the client send packet 11 and when did it receive the reply? What is the difference between these two times? What does this tell you about the time taken to send the two packets across the network? The Wireshark output for the server shows packet 11 arriving at time 10.695405 and packet 12 leaving at time 10.695578 for a difference of 173 µs. The Wireshark output for the client shows packet 11 being sent at time 3.673119 and the reply being received at time 3.675017 for a difference of 1898 µs. This suggests that it took 1898-173=1725 µs for the two packets to cross the network (or 862.5 µs each way). -8-