This week you will further enhance your socket programming skills. What's new in this week:
- Communication between multiple processes
- Indirect communication between sockets
For the basic assignment you will write 3 programs, namely:
- Client
- Forwarder
- Server
In more detail, during this lab you are going to model and implement some simple functionalities of a peer-to-peer (p2p) network.
The main difference of p2p compare to the classical client-server paradigm is that roles (that is, who is the
client and who is the server) are interchanged between peers. For example, in the general case, when you download
a file you act as a client but at the same time you can act as a server by sharing your files to others. Moreover,
in contrast to the client-server model where the client always knows the IP address (i.e, by using DNS service in
order to translate www.google.com to an IP address) and the port number (i.e, if the applications is Web
then the server is listening to Port 80 which is the well-known port dedicated for the particular application) of
the server, however this is not the case in a p2p network. In order to address this problem, peers cooperate and forward
requests and information about the availability of files to each other.
To complete the Lab you have to implement 5 peers:
- One peer will act as a client . This peer issues a query in order to search the p2p network for a particular
file. The only information known to the client is the IP Address and Port Number of a neighboring peer. We will
call this neighboring peer the forwarder. Therefore, the client must communicate with the forwarder in
order to find a particular file.
- One peer will act as a forwarder (broker between a neighbor peer searching for a file and the actual peer that has that
particular file). For simplicity, we will assume that the forwarder keeps information about the availably of files for only three
other peers (that is, three peers apart from the peer issuing the query). These three peers, in our simple scenario, will act
like servers. Again, for simplicity, we assume that each peer (server) announces to the forwarder only one
file (therefore, the forwarder keeps information for only 3 files, one from each server).
- Finally we have 3 peers that will act as servers; by sharing their files to the p2p network. Remember that each
peer (server) announces the availability of a single file to the forwarder.
When implementing the 5 peers (5 peers but only 3 programs) you can make the following assumptions
- Even though in reality a peer can at any given time be a (a) client (downloader) (b) server (uploader) (c)
forwarder (broker) or a combination thereof, in our simple scheme you are going to implement these functionalities
in 3 different programmes. We can do this because in our senario each peer can ether be only a client or only a server
or only a forwarder, and its property (role) will be preserved throughout the execution the senario.
- The peer acting as a client has information about the {IP Address, Port Number} pair of the forwarder. Therefore,
the client can issue a connection (using the connect() system call) towards the forwarder in order to make its request.
- The forwarder peer knows the {IP Address, Port Number} for each one of the three peers (servers). It also knows
the name of the file that each peer (server) is sharing to the p2p network. Therefore, when the client asks for a
particular file, the forwarder knows the {IP Address, Port Number} of the peer (server) that has the requested file.
- Each one of the three peers acting as servers has a unique name which you will give to the peer during its initiation to the
network (it can be a simple input from the command line).
To complete the Lab you should implement the following scenario:
- The forwarder is loaded (remember to use the ifconfig from the command line in order to get the IP address of the system
hosting your forwarder process).
- The forwarder initially listens at a particular port for a connection issued from the client.
- The forwarder knows a priory the {IP Address, Port Number} of each of the three servers.
- As well as the name of the file shared by each server peer. To make your life easier, use a single
character for each file (for example, ‘a’, ‘b’ and ‘c’).
- The three server peers are loaded. We strongly recommend that you execute each server on the same system (hence,
under the same IP) and use ports 3535, 3536, 3537 for the first, the second and the third server peer
respectively.
- Remember to give to each server a unique name (give this value from the command line).
- Each server initially listens at a particular port (3535 or 3536 or 3537) for a connection issued
from the forwarder.
- Finally the client is loaded. The client knows the {IP Address, Port Number} of the forwarder peer.
- The client issues a single request for a single file (you can give the name of the requested file from the
command like during the execution of the client process) towards the forwarder. Remember to include the {IP Address, Port
Number} that the client will be listening (the client will have to listen for a reply from a server).
- The forwarder receives the request and replies to the client with a string:
- "File found" if the requested file is the same as one of the files shared by the server peers.
- Or with "File not found" if the requested file is not available in the p2p network.
- If the file is found. The forwarder gets the {IP Address, Port Number} of the server peer that has the
particular file and issues a connection towards him in order to inform him that a peer (client) is interested
for its file. In the same single message exchanged by forwarder and server, the forwarder includes
the {IP Address, Port Number} of the client (these information were given to the forwarder,
by the client , during the client's request for the particular file).
- The server uses the {IP Address, Port Number} of the client in order to connect with him (Hint:
the client, after issuing the request to the forwarder, must create a listener socket). When the
connection is established the server sends its unique name (string) to the client.
- The client prints the unique name he received from the server to the screen. The end!
What you must show to the TA:
- 3 different codes. One implementing the Client, one implementing the Server and a third implementing the Forwarder.
- You must be able to connect to 3 different systems (using ssh) and load the client in one machine, the forwarder
on another machine and finally the three servers on a third machine.
- When loading the servers you have to define for each one a different name. You also have to remember which
file is handle by which server.
- If we run the client with a file that does not exist. Then the forwarder must answer with a ‘File not Found’ message.
- If we run the client with a valid filename then the forwarder will inform the corresponding server. The server
will connect to the client and send its unique name (the name you gave when you have loaded the server). The client must
print the name onto the screen.
- The end
The aforementioned scenario is graphically illustrated in the following figure:
Appendix
Byte Ordering
Port numbers and IP Addresses (both discussed next) are represented by multi-byte
data types which are placed in packets for the purpose of routing and multiplexing.
Port numbers are two bytes (16 bits) and IP4 addresses are 4 bytes (32 bits),
and a problem arises when transferring multi-byte data types between different
architectures. Say Host A uses a “big-endian” architecture and sends
a packet across the network to Host B which uses a “little-endian”
architecture. If Host B looks at the address to see if the packet is for him/her
(choose a gender!), it will interpret the bytes in the opposite order and will
wrongly conclude that it is not his/her packet. The Internet uses big-endian
and we call it the network-byte-order, and it is really not important to know
which method it uses since we have the following functions to convert host-byte-ordered
values into network-byte-ordered values and vice versa:
To convert port numbers (16 bits):
Host -> Network
unsigned short htons( hostportnumber ) /* Note: hostportnumber can be a value returned from atoi() */
Network -> Host
unsigned short ntohs( netportnumber )
To convert IP4 Addresses (32 bits):
Host -> Network
unsigned int htonl( hostIPv4number )
Network -> Host
unsigned int ntohl( netIPv4number )
Note: To convert from string (e.g, "129.12.33.244" ) to an Internet Address use the fucntion inet_addr(IP_address_as_string);
When you are writting your programms keep in mind the 3 holy rules of programming:
- KISS (Keep It Simple, Stupid)
- FMIRTMIF (First Make It Right Then Make It Fast)
- RTFM (Read The F***ing Manual)