HW 1 - Message Board
Updates:
- 9/2/18: Fixed URLs in C links.
In this homework you will build the simplest type of distributed system—a client/server application. For simplicity we will run both the client and the server on the same computer: a “container” running on the CodeAnywhere web site.
- Setup accounts for Git and CodeAnywhere - follow all steps carefully! Learn the basics of Git and the Linux command line on your own. Familiarize yourself with the CodeAnywhere IDE.
- Create your version of the homework git repository
- Follow the instructions below, writing all of your code in the repository created with the prior step.
You must complete and submit the assignment by pushing all of your final code to GitHub by Friday September 7th at 10AM (note this is AM, not PM). Check your files through the GitHub web interface to ensure that they were all uploaded correctly!
Note: For this assignment you must complete your work in the CodeAnywhere environment.
You will see that I am not teaching you many of the basics needed to solve the assignment. You must figure these things out.
For this assignment I will allow you to work in small groups of up to 3 students, but you still must write and submit all of your own code. This means that you may NOT divide up the assignment and have one student write the C code and another student write the Java code – you each must write all of your own code, but you can discuss your problems with another student as you do so. If I find that multiple students are submitting identical solutions, that will count as cheating and you will fail the assignment!
HW 1: The Simplest Distributed System
A very simple Message Board
Our program will do the following:
The server acts as message board; it will print out any messages that are sent to it along with the name of the sender.
The client connects to the server and sends its name and the message it wants printed. After that it disconnects. The server does not send anything back to the client: I told you this was very simple!
IMPORTANT: During this exercise you may NOT go to any websites except this page, and those listed in the “Allowable Links” sections below. Visiting any other website is cheating!
Getting the code
Before you can begin you need to get a copy of the sample code inside your CodeAnywhere container.
- Clone your repository into your CodeAnywhere container by running: (fill in the URL from your repo website)
git clone YOUR_URL
- Then you should right click on the CS6421 container name and “Refresh” so that the repo files appear in the File Hierarchy.
Starting the Server
The provided server is written in Java so you will need to compile and then run the program as follows.
cd server # change to the server/ directory
javac MsgServer.java # compile the code
java MsgServer # start the server
Note: You will need to run your own copy of the server and you will need to change the IP/hostname in the sample client code to connect to your version of the server, not mine!
Client 0: telnet
The first client you will use to connect to the server won’t require any coding at all–you will use telnet
. Telnet is a very simple program that is useful for debugging network applications and protocols. It simply sends and receives lines of data to and from a server. To run telnet, run: telnet HOST PORT
This will open a TCP connection to the specified HOST
(either an IP or hostname) and PORT
number. If you type some text and hit enter, telnet
will transmit that line of text to the server. telnet
is also always listening for messages coming from the server, and will print them out one line at a time.
Try sending a few messages to verify that your server is working – use localhost
as the host and 5555
as the port.
Once you know the server works, you can then try the different languages below in any order.
Client 1: Sockets in C
To create a socket in C, you first need to get an addrinfo
struct for the host you want to connect to. This is accomplished with the function:
getaddrinfo(const char *hostname, const char *servname,
const struct addrinfo *hints, struct addrinfo **res);
The first argument is a string with the host name or IP, and the second is also a string (not an int like you might expect) with the service port. The third argument provides parameters for the type of socket you want to create, and the final parameter will be filled in by the function if it is called successfully.
Here is a sample usage:
struct addrinfo hints, *server;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if ((rc = getaddrinfo(server_ip, server_port, &hints, &server)) != 0) {
perror(gai_strerror(rc));
exit(-1);
}
Once you have a valid addrinfo
for your server, you can create a socket and connect it:
int sockfd = socket(server->ai_family, server->ai_socktype, server->ai_protocol);
if (sockfd == -1) {
perror("ERROR opening socket");
exit(-1);
}
rc = connect(sockfd, server->ai_addr, server->ai_addrlen);
if (rc == -1) {
perror("ERROR on connect");
close(sockfd);
exit(-1);
}
Now your socket is connected, so you can send
and recv
data with the socket file descriptor returned by the socket()
function. Here are the function definitions from man send
and man recv
ssize_t send(int socket, const void *buffer, size_t length, int flags);
ssize_t recv(int socket, void *buffer, size_t length, int flags);
Both return the amount of data sent or received, and take arguments indicating the socket to send/recieve on, the data to send or a buffer to receive into, the length of data, and flags (which you can set to 0).
Try to edit the c/msg_client.c
file to correctly connect to your Message Board server and send it a name and message.
Allowable links (you may not go to any websites except these):
- C for java programmers
- getaddrinfo API
- socket API
- connect API
- send and receive APIs
- The course’s Piazza message board
Client 2: Sockets in Java
Using sockets in Java is a bit simpler than C. You simply need to create a Socket
object. The simplest constructor for this class takes parameters for the host name and port:
public Socket(String host, int port)
throws UnknownHostException, IOException
Creates a stream socket and connects it to the specified port number on the named host.
Parameters:
host - the host name, or null for the loopback address.
port - the port number.
Be careful–since instantiating this class can cause an exception to be thrown, you will have to put this code inside a try / catch
block.
Once your socket is created, you use this with a PrintWriter object (which you’ve probably used for basic File I/O in the past). This code will create a new PrintWriter
using the output stream of the socket and set the writer to automatically flush data (i.e., send it out the socket):
// sock must be a Socket object
PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
Now that you have a PrintWriter
, you can use functions like out.println("Hello World")
to have it send a string plus a new line character to the server.
If you also want to read from the socket to receive data, you would need to create a BufferedReader
object. We’ll save that for another day.
Try to edit the java/MsgClient.java
file to correctly connect to your Message Board server and send it a name and message.
Allowable links:
- Java beginners tutorials
- Java Socket API
- Java PrintWriter API
- Java BufferedReader API
- The course’s Piazza message board
Client 3: Sockets in Python
Python makes using sockets even easier (or at least with less code).
To create a socket in Python you create a socket object:
import socket
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
This socket object then exposes functions to connect
, send
, and recv
. The connect
function takes a tuple (hostname, port)
while send
simply takes a string of the text to be sent.
Try to edit the python/msgclient.py
file to correctly connect to your Message Board server and send it a name and message.
Allowable links:
- A basic Python tutorial
- Python Socket API
- Python send and recv
- Python Socket How To
- The course’s Piazza message board
Making your code easy to run
If you reach this point you should have three working clients in three different programming languages. Congratulations! There is one final task you must complete before you can submit your code.
You should modify each of your programs so that they will accept command line arguments that determine the host that is connected to, the username sent as the first string, and the message sent. For example:
python msgclient.py "user.somehost.com" "my name" my message"
java MsgClient "192.168.1.1" "Joe" "Hello World"
./msg_client "localhost" "Chen" "this is my message"
You can use any websites you like to learn how to use command line arguments in each of these languages.