CSE 132 (Spring 2010)
Lab 4a: FLAP


Continue working with your design from Studio 7 to implement the flap package.

You can get a C on this lab for code that works, but better grades are available only for clean designs! Take note of everything below, ask questions, and work toward code that is simple and clean.

Your design must include the following classes, all in the flap package, with constructors as follows:

From server to client:
ServerSignonFrame()
one constructor: represents the signon frame as if it were sent to client from server. This class should probably extend ServerFrame.
  • Such constructors are handy for testing, because they doesn't really read any input to obtain their contents.
  • What other methods should ServerSignonFrame have, based on the contents of such frames?
ServerSignonFrame(DataInput din)
another constructor: represents the signon frame actually trasnmitted from client from server.
  • This class should extend ServerFrame.
  • It takes an implementation of DataInput as its parameter.
  • The DataInput is provided so that ServerSignonFrame can read its fields from the server.
  • Go ahead and complete the constructor assuming you have the DataInput object at hand. We can worry about that connection later.

ServerDataFrame(String s)
constructor: represents a data frame as if it were received from the server and contained the String s (useful for testing). This class should extend ServerFrame.
ServerDataFrame(byte[] in)
constructor: represents a data frame actually received from the server. The server provided the array of bytes in, and a String needs to be constructed from that. See String(byte[]).

FLAPInputStream(InputStream)
This class's primary responsibility is to provide the method ServerFrame readFrame().
  • You are given an InputStream, but if you want to deal with richer types on input, use the I/O decorations to create richer streams for yourself. For example, DataInputStream provides methods to read 2- and 4-byte integers.
  • The ServerFrame readFrame() method deserves some thought. It has to read enough of the message to know what kind of frame to create. Once the proper frame is known, it can be constructed and the payload can then be processed to populate its own fields. The constructors above provision for that by accepting suitable inputs.
  • One problem here is how to get FLAPInputStream's readFrame() to provide a DataInput to ServerSignonFrame.
    You want to give the constructor a DataInput to process the current frame only! Don't just hand over the socket's input stream, because if the constructor reads too far, or not far enough, the reamining input will not be processed correctly and such errors are hard to find.
    • A handy class to help with that is ByteArrayInputStream. That class will take an array of bytes (such as the payload of the message) and provide a normal input strream using only those bytes.
    • Think about how to use decoration to make a DataInputStream out of that.
From client to server:
ClientSignonFrame(String username)
constructor: represents the version of a signon frame sent from the client to the server. This class should extend ClientFrame.
ClientDataFrame(String s)
constructor: makes a frame for sending from client to server. This class should extend ClientFrame.
FLAPOutputStream(OutputStream)
This class's primary responsibility is to provide the method void writeFrame(ClientFrame f). The following statements are meant to guide your thinking so as to create the simplest implementation of this part of the flap package:
  • Every framed message from the client to the server has the same format in terms of the asterisk and the sequence number. Such code should appear in only one place.
  • The frame type does differ by frame. How do you ensure that a sutiable method to get the frame's type is available for all extensions of ClientFrame even though such an implementation is not possible in ClientFrame itself?
  • The framed message requires a payload and its length must be known before the payload is sent.
  • The safest approach would require extensions of ClientFrame to provide the contents of the payload, so that the calculation of its length occurs in just one spot. How is such a method provisioned for the extensions even though ClientFrame itself does not know how to produce a payload? The ClientSignonFrame and ClientDataFrame classes just need some kind of output stream to create their payload. The method provisioned could pass such an object.
  • The ByteArrayOutputStream would be a good place to look for methods that help you achieve these goals. It allows an output stream to be built without actually sending bytes over the socket. Once all the writing is done, you can get the bytes that would have been sent, know their length, and then send the appropriate data to the server.

Notes:

One challenge in sending and receiving data is effecting the proper data format outbound and inbound. Below are some examples.

Pseudo Demo

When you are ready, show your work to the TA and get checked off for this lab.
Thanks to Matt Gokel for providing the following:


Last modified 08:59:23 CDT 03 June 2010 by Ron K. Cytron