CNT5505 Course Project 1

 

The code can be written in both C/C++.

In a peer-to-peer content distribution network, a client is a user who wishes to download some files. Over the time he may have got a number of files, thus, when asked, he can also upload some of the file he has to other clients. The question is how to make other clients know that he has these files. There are many ways to do this, and in our project we will adopt the simplest method, in which there is a centralized server who keeps track of all the information of the clients in the network (this is the ``tracker’’ in BT). In this project, there will be n files where n is 64. Each client maintains a 64-bit vector, called ``file vector’’ indexed from 0 to 63, in which bit i is 1 if it has file i and 0 otherwise. The purpose of this project is to set up basic client-server communications.

For the client:

1.    Initialization. The client will be invoked with a command line which contains two arguments. The first argument may be the server’s IP address in dotted decimal notation or the server’s domain name. If it is the IP address, the client calls the gethostbyaddr() function to get the domain name and prints out. If it is the domain name, the client calls gethostbyname() to find the server’s IP address and prints it out. The second argument is the name of a config file which the client reads to find its id, the server’s listening port, its own listening port, and its initial file vector; the client should print out such information. The config files are different for different clients and will be supplied by me.

2.    Connect to the server. The client tries to connect to the server by first creating a socket and then calling the connect() function. If the connection is successful, the client prints out a success message; otherwise it quits. In this assignment, all connection is TCP.

3.    Report to the server. The client then sends the server a message with information of its id, its listening port, and the file vector. The client does this by filling in a ``Packet’’ struct defined in common.h, and send the struct to the server.

4.    Wait for commands. The client enters an infinite loop. The client will use the select() function to get user inputs and to read message from server. It accepts two commands, ``f’’ and ``q’’:

·       If the user types ``f’’, the client will ask which file the user wants and the user will input the file index. If the user inputs, say, 10, the client first checks if it has file 10. If yes, it prints out a message like ``I already have file 10.’’ Otherwise, it sends a message to the server saying that ``can you tell me who has file 10?’’. The server will reply with a list of clients who has file 10. After receiving the server’s message, the client prints out the list, then waits for the next command.

·       If the user types ``q’’, the client quits: a) it first sends the server a message saying that it wishes to quit, b) waits until server closes the connection, c) terminate the program.

5.    Auxiliary functions. The client also reads commands from the server. For this project there is only one command: quit. If the server sends the client this command, the client will close the connection by calling the close() function and exit.

For the server:

1.    Initialization. The server first creates a socket, binds it to port 5000 (5000 is the so-called ``well-known’’ server listening port for our project), and calls the listen() function to wait for connection requests from this socket.  

2.    Accept requests. If there is a connection request, the server calls accept() to accept the request. The integer returned by accept() is the socket id through which server will communicate with this client. The server then reads the message the client sends which contains the client’s ID, listening port, and file vector.   

3.    Answer client queries.  If a client sends the server a query for a file, server first prints out the client’s ID, IP address (the client’s IP address can be found when calling the accept() function and can be later stored), and the file index the client is asking for. The server then prints out the IDs of all clients who have the file (who have reported to the server by this time), and sends this list to the requesting client.

4.    Respond to user command.  The server receives only one command from the user, ``q.’’ If the user types in this command, the server sends to all clients a ``quit’’ message, and waits until all clients have closed their connections with the server, after which it will exit.

5.    Respond to client quit message.  If a client sends a ``quit’’ message to the server, the server prints out a message like ``(client ID) at (IP address) wishes to quit,’’  then closes the connection with this client.

 

You can write your own code from scratch or can start with a template code (here) which also includes the client config files. To use it, copy template.tar to your working directory, type ``tar xvf template.tar,’’ then type ``make.’’ Then you will see two executables, server, and client. To invoke the server, simply type ``./server.’’ There are many ways to invoke the client, which you may find out by reading the client code. One simple way is, for example, by typing ``./client –m localhost  -h 5000.’’ It is recommended that when debugging, run 3-4 client processes and the server process on the same machine.