CS 600.444 Group 7 Project 2 Members: Josh Smith, Leah Hanson, Matt Morris We have written the project in Haskell. It is divided into the TinyControl Library and a ServerApp and ClientApp. ServerApp and ClientApp just call the library functions. With Prof Haberman's permission, we simplified the API to be tailored to the specified test app. To Run the Test App: 1) Download & install the Haskell Platform for you system from: http://hackage.haskell.org/platform/ 2) In our project folder, run "cabal configure" and then "cabal build". 3) It may ask you to download additional packages. You can do this using "cabal install <packagename>". cabal configure/build will tell you the name of the package you need if you need to install something. 4) At this point, cabal build has succeeded. (If you have any trouble, please email us -- it builds on our machines, but sometimes package versions can be an issue.) 5) The serverApp executable is located at ./dist/build/server/server 6) The clientApp executable is located at ./dist/build/client/client 7) Start the server, then run the client as many times as you would like, including multiple clients at the same time. It is set up to run on localhost. The server test application sends the file "testdata" to the client. The client requests the file, receives it, and then prints it out to stdout. If you change the content of the file "testdata", then the data sent will change. The Source Code: In the main project folder, ServerApp.hs and ClientApp.hs are the test application. The Library Code is located in the TinyControl folder: Time.hs: some helper methods for working with Times (moving between seconds, NominalDiffTimes, and UTCTimes) Setup.hs: This was generated by the cabal build tool; it is used by cabal build to compile out project. Common.hs: UDP send/recv/etc code that is shared between the Client and Server libraries. Packet.hs: Data types and helper methods associated with the DataPacket and FeedbackPacket types. This is shared by the Client and Server, which makes communication easier. Client.hs: This is the library used by the client application. All the client can do is say "this is the server I want to get something from, and this is the data I want to send to it.", by calling "wantData". Server.hs: This is the library used by the server application. All the server can do is say "Clients will contact me at this port. Here is the function that will turn their message into the data to return. The function that I give you can do input/output (read from disk, etc).". The server library then takes care of forking off a thread to handle each client and send the data. Some Implementation Details: We handle rate limiting by sending all the packets that we are allowed to (upto the average rate), and then waiting until to send more packets until the amount of data we send initially divided by our wait time is no greater than the maximum average rate. The initialization protocol is that the client sends the server a packet. This packet can inidicate what data to send; then the server starts sending. The first packet that the client gets from the server determines where the the client will send all feedback packets. This allows the server to talk to multipled clients, since each of them can be moved off to their own port on the server. We did not implement section 3.2.7. (Initializing Loss History After First Loss Event). We think we managed to do the rest.