Note: All your code should compile and run on itsunix. Programs that have been developed on your personal computer and do not run on itsunix will not be graded and will receive 0 points.
The goal of this assignment is to implement a simple client-server system. You can use Python or Java. The basic functionality of the system is a remote calculator. You first will be sending expressions through the client to the server. The server will then calculate the result of the expression and send it back to the client where it is displayed. The server should also send back to the client the string "Socket Programming" as many times as the absolute value of the result from the expression.Your server will start in a "passive mode", in other words, it will listen to a specified port for instructions from the client. Separately, the client will be started and will connect to the server on a given host name or IP address plus a port number. The client should take as input from the user the host name or IP address plus the port number and an expression to be calculated. Consider solving an expression that would generate relatively big result, allowing you to test transmission of multiple packets (see TCP and Reliable UDP below for more details).
The client, when started, should request the following information:
The client should make sure that the specified port is valid, in other words, the client should check if the port is in the range from 0 to 65535 and if not should display a message of the format "Invalid port number. Terminating."
The client, then, will try to connect to the specified server on the specified port and transmit the expression to the server.
The interaction flow between the client and server is as follows:
Your remote calculator should support the four basic mathematical operations plus various combinations of them:
Note that you have to handle network errors. Make sure that you verify in your client code if the connection to the server was successful. If the connection failed, your client program should display an error of the format: "Could not connect to server. Terminating."
Also make sure your client returns an error if the result was not successfully received from the server. The client should display the following text: "Could not fetch result. Terminating."
The client and server using Reliable UDP will operate as follows:
NOTE: When sending large amounts of data over UDP, you might need to transmit multiple portions. This is because the UDP buffer fills up before the total amount of data is sent. Let's look at an example - say that your server needs to send a total of 5120 bytes but the UDP buffer is only 512 bytes. In this case, even though your server said that it is sending 5120 bytes, the UDP on the client delivers the data in 512 byte chunks because of the buffer size. A program that sends an ACK only if the received number of bytes is the same as the expected number of bytes will fail to send an ACK in this case, which eventually will cause the connection to timeout and the server will fail to send result to the client. To avoid such problems, your programs will have to send an ACK for each received portion of data, keep track of how much of the entire message had been received and display the result only if the total amount received is equal to the value sent in the length message. This problem will probably not occur when your client sends data to your server because the entire expression will fit into a single packet and thus it will arrive all at once. However, you will want to test your system with large enough results to confirm that it works correctly.
Below are some output examples, to help you format your programs display. The format of both the TCP and UDP programs should be the same - that is why we don't have separate examples for TCP and UDP. The only difference between running TCP and UDP programs is going to be the names of the programs to be run (see section "Language Choice and File Names" for naming conventions). Because we only have access to one development machine (itsunix), you will be running both the server and the client on the same physical machine. For this purpose you need to use the localhost address (or 127.0.0.1) when running your programs.
For Java, the program names should be:
To compile your Java code, use the following commands:
For Python, the program names should be:
To compile your Python code, use the following commands:
NOTE: Pay attention to all of these directions carefully. Make sure that you name your files and format your messages as specified in the assignment. An automated program will be used for grading and if there are any deviations, you will lose points!
Expression/Implementation | 1+1 | 5+5 | 20+20 | 50+50 |
---|---|---|---|---|
Overall delay (TCP), s | ||||
Overall delay (UDP), s |
Expression/Implementation | 1+1 | 5+5 | 20+20 | 50+50 |
---|---|---|---|---|
Achieved throughput (TCP), bps | ||||
Achieved throughput (UDP), bps |
Note: Consider running your experiments from the same network. For example, if you run your UDP experiments from campus and your TCP experiments from home, different delay characteristics of the campus and your home network will skew your results.
Below is a breakdown of points for this assignment. In addition to correctness, part of the points count towards how well code is written and documented. NOTE: good code/documentation does not imply that more is better. The goal is to be efficient, elegant and succinct!