Phase
1: Messenger with P2P tree framework(Complete sockcomm.c, and steps 1-16 ,21
and 25 in peer.c)
Due:
24th March (midnight)
Phase 2: P2P File retrieval (Complete remaining steps in peer.c)
Due:
21st April (midnight)
In this programming assignment, you are asked to develop a simple peer-to-peer (p2p) file sharing system that emulates the behavior of Gnutella with simple messaging facility. The objective of this project is to let you get hands-on experiences in computer network programming, in particular, socket programming, and in network application development.
You are asked to develop only one program, called 'peer'. Multiple hosts execute their own copy of this program in certain order (which will be elaborated later) to form a p2p system. We call such a host with a running 'peer' program as a 'peer host'. Every peer host designates a directory containing several files as its shared directory when it started. Once a peer-to-peer system is set up, any peer host can use command 'get ' to download the specified file from some peer host holding the file. In order to simplify the problem, we assume all shared files have distinct file names.
What
you need to do?
You are provided with template source codes: peer.c, peer.h, sockcomm.c and
sockcomm.h. In peer.c and sockcomm.c, you can follow the instructions to fill
missing parts. You are responsible for declaring additional variables and for
adding some code blocks if necessary.
You are also provided with a compiled binary code 'peer'. It can be executed on SunOS machines. You can follow the example in the later part of this description to see how the program is supposed to behave.
You are not restricted to work on the template provided. As long as your final program has the same function of 'peer' (including output messages), it will be acceptable. Any programming language is acceptable.
In order to compile your program, put files peer.c, sockcomm.c, sockcomm.h and Makefile under the same directory. Change your current working directory to that directory. Type command "make" and you will get binary code "peer". You can also use command line "gcc -lsocket -lnsl peer.c sockcomm.c -o peer" under Solaris, or use "gcc -lnsl peer.c sockcomm.c -o peer" under Linux.
If you don't have 'gcc' on your CS or itlab machine, that is, only because you haven't loaded the module yet. You can load the module using command 'module load soft/egcs/3.4'. In order to avoid doing this repeatedly, you can add this command line into your '.cshrc' file that is under your home directory.
Forming
a P2P System:
The SYNOPSIS of the 'peer' program is as follows:
peer pathname [ hostname ]
pramod@venus
(~) % mkdir /home/grad05/pramod/venus
pramod@venus (~) % echo "this is mydoc1" >
/home/grad05/pramod/venus/mydoc1
pramod@mercury
(~) % mkdir /home/grad05/pramod/mercury
pramod@mercury (~) % echo "this is mydoc2" > /home/grad05/pramod/mercury/mydoc2
pramod@atto
(~) % mkdir /home/grad05/pramod/atto
pramod@atto (~) % echo "this is mydoc3" >
/home/grad05/pramod/atto/mydoc3
pramod@caesar
(~) % mkdir /home/grad05/pramod/caesar
pramod@caesar (~) % echo "this is mydoc4" >
/home/grad05/pramod/caesar/mydoc4
pramod@venus (~) % peer venus
pramod@mercury (~) % peer mercury venus.cs.umn.edu
pramod@atto (~) % peer atto mercury.cs.umn.edu
pramod@caesar (~) % peer caesar mercury.cs.umn.edu
get mydoc4
The file 'mydoc4' is downloaded from 'caesar' to 'venus' and stored in the cwd (current working directory) of the 'peer' program. In my example, you can find the downloaded file at '/home/grad05/pramod/venus/mydoc4'. The following figure shows how the peer-to-peer system looks like following aforementioned steps.
Joining
the P2P System:
In our system, a new peer host can join the existing p2p system from any
present peer host in the system. Therefore, every peer host has to have a
listen socket to accept connection request from new peers. In our program,
every peer host has a listen socket on port for this purpose (port # 10419 in
case of example peer, pick a random port to avoid running into conflicts). A
TCP connection is set up between the new peer host and its joining peer host.
They are called a 'neighbor' to each other.

Figure 1. A Tree-based P2P System
Chat
service:
After the peer-to-peer system is
setup, a user can type command like 'IM aqua Hello World' on a peer which is directly
connected to aqua. Only aqua will receive this message along with information
about the sender. If any peer wants to send a message to every other node in
the peer-2-peer tree, the client can type 'IM broadcast Hello World'. All
directly connected nodes/peers receive this message and they intern broadcast
this message to all of their other directly connected peers. This way the
message propagates through the peer-2-peer tree and reaches every node in the
system.
Lookup
service:
After the peer-to-peer system is set up, a user can type command like 'get mydoc4' on a peer host to download the specified file. This actually involves two steps - lookup and download. The lookup service used in our simple file sharing system is based on flooding. In the previous example, after 'get mydoc4' is input on peer host 'venus', a message looks like 'GET mydoc4 128.101.189.164 36953' is constructed. In this message, '128.101.189.164' is the IP address of host 'venus'. '36953' is the port number of the listen socket that 'venus' has created to set up a data channel (or TCP connection) with the peer which has 'mydoc4'.
This message is flooded to all neighbors of 'venus'. For every peer host receiving this message, they first do a local lookup to see whether the specified file is in its shared directory. If it is not there, the peer host forwards the same message to all of its known neighbors, except the one from which it got the message. If the specified file is in a peer host's shared directory, it makes a connection request to the originating peer host whose IP address and port number is in the message (in our example, it should make a connection to host 128.101.189.164 at port 36953). Once the connection is set up, the requested file is sent in multiple IP packets in the case where the file's size is bigger than 1500 bytes.
Download
Files considering Timeout:
A new listen socket needs to be created when a 'get' command is received from
stdin. Each time, the port number will be different so it is included in the
"GET" message. Since such listen sockets have timeout requirement, a
new process is created using fork(). The new process uses a select() with
timeout period, e.g., 10 seconds, to wait for connection requests on the listen
socket. In our example, 'venus' creates a listen socket waiting for connection
request from some peer host holding 'mydoc4'. However, it's possible that
'mydoc4' doesn't exist in any peer host. To handle this case, such listen
socket has a timeout period, for example, 10 seconds. If there is no connection
setup after timeout, the listen socket is closed and a message "admin: the
requested file doesn't exist in the p2p system" is displayed. On the other
hand, when the download is completed, the child process should display a
message "the requested file has been downloaded successfully". Like
this, this fork structure should allow the user to request a new file while the
previously requested files are being downloaded from peers.
Servicing
the Files downloaded from Other Peers:
When a peer downloaded a new file from other peer, the file can be provided to
other peers which request it. Therefore, you need to update the file list after
completing each download. For example, in Figure.1, assume that 'mercury' downloaded
'mydoc4' from 'caesar' and 'atto' requests 'mydoc4'. Since 'caesar' has
'mydoc4' now, it can provide it for 'atto' instead of 'caesar'.
Support
of Transfer of Big File:
You should support the transfer of big file, such as an mp3 file of 3MB. You need
to make a loop structure in the sending and receiving sides in order to allow
for the multiple transfers of file packets.
Terminate
a Peer Host:
Use 'Ctrl-C' to terminate a copy of 'peer'. It is required the termination to
be handled gracefully, e.g., the connected neighbor(s) should display message
like "admin: disconnected from 'mercury.cs.umn.edu(35032)'". Be
assured that there is no crash on any neighboring peers.