CSE 461: Introduction to Computer Communication Networks, Autumn 2012
  CSE Home   About Us   Search   Contact Info 
Home
Overview
Course email
Anonymous feedback
View feedback
Course wiki
Home Virtual Machines
Homework Turnin
Class GoPost Forum
Gradebook
Schedule
Hw/Project List
    Project 2
Out: Wednesday October 3
Due: Thursday October 11 (midnight)
Turnin: Online
Teams: Yes


Assignment Overview

This project is about layering, framing, and encoding of data. The class material and text have addressed these, but mostly at the physical and link layers. We'll be looking at the some of the same issues, but at the application layer. Additionally, like Project 1, this project includes something of a warm-up: you'll ease into writing some Android-specific UI code.

Starting with this project, we're implementing a set of network layers that make building networked applications easier. (After that, we'll build a network application, or two.) We could begin with either UDP or TCP, but because we're going to want better reliability characteristics than UDP provides, we choose TCP as the starting point. This project addresses two shortcomings of TCP, relative to our eventual needs:

  1. TCP doesn't provide any kind of framing.
  2. TCP sends a byte stream, but provides no help to the receiver understanding what the bytes represent
We fix the former by implementing a new networking layer (TCPMessageHandler) that defines a simple frame format. We fix the latter by adopting a convention at the application level that the payload is represented using JSON (Javascript Object Notation), a widely adopted data interchange format. The results in some data transfers that look like this:

length JSON encoded payload

Each frame begins with a length field, giving the length of the payload, which is a single application layer message encoded in JSON. Both of these are discussed in more detail below.

When you're done, your network stack will look like this:

An application can choose to use TCP as a stream, bypassing the new layer, or it can choose to use TCPMessageHandler to create messages on top of TCP. In fact, an application could mix both modes of communication, if it wanted.

Note that TCPMessageHandler is a networking layer, not part of any application. Thus, its design and implementation must be independent of the specific applications we build in this project.

Application Functionality Overview

We'll re-implement essentially the same applications we implemented in Project 1. What you should be watching for in this project, and subsequent ones, is how much easier it gets to write and use those two applications. In terms of performance, we hope that the added convenience doesn't make things run much slower.

ping

We reimplement ping to send messages in the new, framed format. We use EchoTCPMessageHandlerService, an implementation of Echo that understands the framed format, as the server. Because we're using messages, it's now possible for the client to send a length 0 message to the echo service, and it should do that. From the user's perspective, the only change is that the Project 2 ping runs on top of TCPMessageHandler (so, TCP) only; we no longer use or report results for UDP.

dataxfer

In Project 1, the number of characters transferred from the dataxfer server to the client was determined by the port to which the client connected. That's an unrealistic mechanism. In Project 2, we allow the client to specify the amount of data to send. It does that by sending a control message to the server as the first transmission over the connection. The control message contains a JSON encoded payload, in particular, a single JSONObject with one key-value pair. The key is transferSize, and the value is an integer representing the number of bytes to transfer. Having received that control message, the server returns transferSize bytes to the client, sending these as messages containing no more than 1000 bytes. Here's a picture of the protocol when 2500 bytes are transferred:

All data is sent as messages (i.e., using TCPMessageHandler frames.) Only the control message (in blue) carries a JSON encoded payload; the data messages carry raw bytes.

(ConsoleApps) Implementation Details and Requirements

Here's a summary of the files you'll work on.

Source File /
Interface File
Eclipse Project
TCPMessageHandler.java /
TCPMessageHandlerInterface
Net
(edu.uw.cs.cse461.Net.TCPMessageHandler)
PingTCPMessageHandler.java /
PingInterface.java
ConsoleApps
DataXferTCPMessageHandler.java /
DataXferInterface.java
ConsoleApps
DataXferTCPMessageHandlerService.java /
None
Net
(edu.uw.cs.cse461.Net.TCPMessageHandler)
default.config.ini /
None
ConfigFiles
PingTCPMessageHandlerActivity.java /
None
Downloaded into AndroidApps
(edu.uw.cs.cse461.AndroidApps)

You should create files PingTCPMessageHandler.java, DataXferTCPMessageHandler.java, and DataXferTCPMessageHandlerService.java.

TCPMessageHandler.java

This class handles sending messages over a TCP stream. Its interface allows users to pass in data of various types. The data is converted to a byte[] payload, prefixed by the length of the byte[], and then sent over the underlying TCP socket:

lengthpayload

The receiver reads the length field, then the payload, and then converts the byte[] it has read into the type requested by the client as part of the read call.

The integer length prefix is sent in binary, as four bytes in little endian order.

All required methods of TCPMessageHandler are defined in the skeleton code, but some are missing implementations. Note that the methods for writing and reading the integer length field are inverses of each other: if you encode an integer using one and then decode it using the other, you should get the original integer back. The same relationship holds between send and read routines for a particular data type: the send routines convert into byte[], and the read convert from byte[] back to the original data type.

To interoperate, all our implementations must agree on how to translate between the types supported by the interface and byte[]. The schemes used are these. A String is converted to a byte[] using String.getBytes(). A JSONObject or JSONArray is converted to byte[] by first converting to a String and then applying the String transformation.

Finally, we're building code that uses the network, and so security should come to mind. In writing our projects, we're not worried about malicious remote users (those whose goal is to interfere with our goals), mainly because there's little incentive in that relative to the amount of work required. On the other hand, we are worried about what effect simple programming errors in code we're talking to might have on our code, in part because we're likely to talk to buggy code as we develop. For this project, you should worry about bad length prefixes. The length value might simply be preposterous (e.g., negative, or enormous). TCPMessageHand's interface provides a method to give the client some control over what "preposterous" means. Alternatively, the length field might be reasonable, but wrong. You should continue to guard against blocking forever on a read by always setting timeouts on sockets. The code relies on the creator of the Socket to set the timeout. The creator is not TCPMessageHandler (the socket is passed in as an argument to TCPMessageHandler's constructor), so the timeout is set in some other code. However, you should be sure it is always set. (You don't have to try to verify in your TCPMessageHandler code that there is a timeout. In most cases it's a bug in the client code if it hasn't been sent, but it's a decision the application makes. Your code should be prepared for timeouts, however.)

PingTCPMessageHandler.java

This is Ping console client code. It should send a length 0 message to EchoTCPMessageHandlerService and measure the elapsed time to receive a reply. The is almost identical to your Project 1 ping client code, except that we no longer use UDP and you're sending TCPMessageHandler messages rather than sending a TCP byte stream. You need to create this file.

DataXferTCPMessageHandler.java

This is the data transfer application client. It too is very like its Project 1 cousin. The main change is the one described above: the client sends a control message to the server indicating how many bytes it would like to transfer, rather than that being determined by the port the client connects to. You need to create this file.

DataXferTCPMessageHandlerService.java

The server side of the message based data transfer application. It should read the control message sent by the client, then respond by sending the amount of data the client requested as a sequence of one or more messages. You need to create this file.

default.config.ini

You're creating new applications and services. These must be entered into the corresponding lists of components to be loaded that are given near the top of the config file: net.services for services, and console.apps for apps.

Your config file contains properties for echotcpmessagehandler, but not for the data transfer service or application. Add (and use) these: dataxfertcpmessagehandler.server, dataxfertcpmessagehandler.port, dataxfertcpmessagehandler.sockettimeout, and dataxfertcpmessagehandler.ntrials. Their meanings are the same as the similarly named properties used in Project 1.

PingTCPMessageHandlerActivity.java

Android UI code, discussed in the next section.

Android Project Component

General Overview

Our goal at this point is simply to get some experience working with an Android UI. For that reason, on Android we implement the message-based ping application only. You must download several new files to obtain skeleton source for this. Those files are listed in a table below.

It will probably be useful to look at (and use) the EchoRaw Android application that is part of the skeleton code. That should help you understand what the control flow of Android applications is like and how your code accesses and manipulates the UI components. To run the Android component of the project, right-click on the Eclipse AndroidApps project, then Debug As, then Android Application. If you have a phone connected by USB, the app should come up on the phone; otherwise an emulator is launched. The first screen lets you choose a configuration file, but there's only one at this point, so just click ok. The next screen lets you launch individual apps.

You can observe what EchoRaw does by running it. Looking at its implementation should help you connect Android application behaviors with how they're implemented. The main components of EchoRaw are its java file, its layout, and its entry in the Android manifest. All are located in the Eclipse AndroidApps project. The layout is located in subfolder res/layout, and is called echoraw_layout.xml. Double-clicking on it brings up a UI editor. The manifest file, AndroidManifest.xml, is located after the folders in the project. It lists the components of the application. Double-clicking on it, and then selecting the XML view (a tab at the bottom of the editor pane), you'll see an <activity> section for EchoRawActivity near the end of the file. When you create your activity, you'll have to create an <activity> section for it in the manifest.

Because of some technical constraints, our infrastructure's config.ini file is located in the project's assets folder, and is given a surprising name: default.config.ini.png. It's just a text file. To edit it, drag-and-drop it into Eclipse's editor pane; double-clicking on it doesn't do anything you want.

Android Component Downloads

Download cse461Project2Files.jar and un-jar it to produce directory cse461Project2Files. In that directory are the four files listed below. They should be copied into the directories associated with them in the table.

FileDirectory
PingTCPMessageHandlerActivity.java .../AndroidApps/src/edu/uw/cs/cse461/AndroidApps/
pingtcpmessagehandler_layout.xml .../AndroidApps/res/layout
activity_android_app_manager.xml .../AndroidApps/res/layout
This is a bug fix release. It replaces an existing file with the same name.
AndroidAppManager.java .../AndroidApps/src/edu/uw/cs/cse461/AndroidApps/Infrastructure
This is a bug fix release. It replaces an existing file with the same name.

(Once you've downloaded them, you may need to select the File/Refresh menu item in Eclipse.)

The UI's Layout

In the Eclipse project explorer, double-click on the layout file you just downloaded. You'll see something like this:

This is the graphical view of your UI. A view of the XML file that defines it is also available by clicking on the XML tab just below the image of the UI.

Ignoring the grey band at the top containing the application name (which is provided by Android), the UI has four components. At the very top is a small text field where the IP of the phone will be displayed; code to set it is included in the skeleton. Below it is a single text box available for user input. It will be used to specify a remote host name. Below that is an inappropriately labeled button; when clicked, your code should perform a ping. The result of the ping is displayed in a textbox below the button. It's visible here only because I have selected it, but normally you don't see any border for it. It's easy to spot in the XML view of the UI, though..

You need to do two things to the UI:

  1. Add a text box that allows the user to specify a port on the remote machine.
  2. Change the label on the button to Ping.
You can do both these things using either the graphical or the XML views of the layout. When you're done, your UI should look like the pingrpc_layout.xml already in the skeleton code (which looks like the echoraw layout after removing one text box).

The Manifest

Add the following to the list of activities named near the bottom of file AndroidManifest.xml:

    <activity
        android:name=".PingTCPMessageHandlerActivity"
        android:label="PingTCPMessageHandler" >
    </activity>

The Code

The PingTCPMessageHandlerActivity.java skeleton code knows how to establish values in the existing UI components. It has also tied clicking on the button to invocation of an event handling method, onGoClicked(). Most of your code should go in that method. Your code needs to read the server IP and port values from the UI components, perform a single ping to that server's EchoTCPMessageHandler service, and then report the elapsed time in the output UI widget. Unless you're trying to interact with the UI, your code in the Android app is exactly like the code you already wrote for the console version. In later projects it will be important to factor your implementation so that the Android and console versions can share the bulk of what you write, but for this project the implementation is so small that it doesn't matter.

The default.config.ini(.png) File

You must list your new activity class under the android.apps property. You may also want to adjust other values in the same ways you did in Project 1 - it's just a config file for our application.

Android Background Information

Brief additional background on Android applications is available on this page.

What to Hand In

Submit the code files you created or modified, following the same scheme as in Project 1 (described in section "What to Turn In" in the Project 1 assignment page).

Computer Science & Engineering
University of Washington
Box 352350
Seattle, WA  98195-2350
(206) 543-1695 voice, (206) 543-2969 FAX
[comments to zahorjan at cs.washington.edu]