Hello, if you have any need, please feel free to consult us, this is my wechat: wx91due
COMP3331/9331 Computer Networks and Applications
Assignment for Term 3, 2024
BitTrickle File Sharing System
1. Goal and Learning Objectives
- The server authenticates users who wish to join the peer-to-peer network, keeps track of which users store what files, and provides support services for users to search for files and to connect to one another and transfer those files directly.
- The client is a command-shell interpreter that allows a user to join the peer-to-peer network and interact with it in various ways, such as making files available to the network, and retrieving files from the network.
You will additionally submit a short report.
On completing this assignment, you will gain sufficient expertise in the following skills:
- A deeper understanding of both client-server and peer-to-peer architectures.
- Socket programming with both UDP and TCP transport-layer protocols.
- Designing an application layer protocol.
2. Assignment Specification
- “A” informs the server that they wish to make “X.mp3” available to the network.
- The server responds to “A” indicating that the file has been successfully indexed.
- “B” queries the server where they might find “X.mp3”.
- The server responds to “B” indicating that “A” has a copy of “X.mp3”.
- “B” establishes a TCP connection with “A” and requests “X.mp3”.
- 6“A” reads “X.mp3” from disk and sends it over the established TCP connection, which “B” receives and writes to disk.
Figure 1: Sharing a file with BitTrickle
2.1. Authentication
- The username is unknown; or
- The username is known, but the password does not match; or
- The user is currently active (see 2.2. Heartbeat Mechanism).
Should authentication succeed, the peer should become active (see 2.2. Heartbeat Mechanism) and the user may start issuing commands (see 2.3. Client Commands).
The list of users authorised to join the network is stored in a credentials file. You may assume that during marking any username and password entered by the user will be non-blank and well formed, as per the rules of the credentials file (see 2.1.1. Credentials File).
The credentials file is a text file available to the server that contains the usernames and passwords of those authorised to join the network. This file is not available at the client.
Usernames and passwords are each limited to 16 characters and shall consist only of printable ASCII characters. Each line of the credentials file contains one username-password pair, separated by a single space, with no leading or trailing whitespace, and is terminated by a single '\n' newline character.
You may assume that each username in the credentials file will be unique, but you should not assume any particular ordering of the credentialsfile. You may assume that the server has sufficient resources to store all credentials in main memory, should you choose to read the file once on server startup.
The credentials file will be named credentials.txt. It will be in the working directory of the server, and it will follow the format and rules stated above.
Do not hard code any path to the credentials file, or assume any name other than credentials.txt, within your server program. The program must read the file credentials.txt from the current working directory. Failure to do so will likely result in your applications not passing any testing.
A sample credentials file is provided on the assignment page of the course website. A different credentials file will be used during marking. You may assume the file will be present in the working directory of the server, will have the same name, will have the necessary permissions, will follow the same format and rules, and will remain present and unmodified for the lifetime of the server.
Your server program is not expected to create new or alter existing accounts, and your server is not expected to modify this file in any way.
2.2. Heartbeat Mechanism
To achieve this, BitTrickle utilises a “heartbeat” mechanism. These are messages sent periodically by each client to the server to remind the server that the peer is still active. Specifically, after being authenticated, the client should send such a message every 2 seconds. Meanwhile, the server should only consider a peer active if, within the last 3 seconds, the user authenticated, or the server received a heartbeat from that peer.
You may assume that the 1 second difference is sufficient to account for any reasonable network and server latency. You may also assume that heartbeat messages will be delivered reliably.
Note, the heartbeat mechanism will need to run in a separate thread of the client so that the client can concurrently accept and act upon user input (see 3.2. Client Design).
2.3. Client Commands
While it is good programming practice to validate all user input, you may assume that during marking all user input will be well formed. That is, only valid commands will be entered, in lower case, and where the command takes an argument, then an argument will be given, with a single space separating the command and the argument. The argument will also be well formed, case sensitive, and contain no internal whitespace. Furthermore, user input will contain no leading or trailing whitespace.
The client should query the server for any active peers that have published (i.e. shared) a file with an exactly matching filename. If there are multiple such peers, the server (or client) may select one arbitrarily. The client should then establish a TCP connection with the peer, download the file to its working directory, and print a message indicating success. If there are no active peers with a file that matches, then the client should print a message indicating failure.
2.3.2. lap
The client should query the server for a list of files that are currently published (i.e. shared) by the user and print out their names. The file names may be printed in any order. If the user currently has no published files, then a suitable message should be printed.
Note, this is intended as a server request so that the client isn’t required to maintain any persistent state. That is, a user can publish one or more files, go offline, and should they come back online, then any files previously published will still be listed without any need to store that information locally or re-publish.
2.3.4. pub <filename>
The client should inform the server that the user wishes to publish a file with the given name. This command should be idempotent, that is, executing it repeatedly with the same argument should have no additional effect. The file should remain published until such time as it may be unpublished, regardless of whether the peer remains active. That is, a user can publish one or more files, go offline, and should they come back online, then any files previously published will still be shared without any need to re-publish.
You may assume that the file exists in the working directory of the client, with the necessary read permissions, and will remain present throughout testing.
The client should query the server for any files published by active peers that contain the case sensitive substring within their name and print out the names of any such files. The list should not include any files published by the user issuing the query. The file names may be printed in any order.
If there are no files published by active peers that contain the substring, then a suitable message should be printed.
The client should gracefully terminate. Note, this requires no server communication. Given the client will no longer send heartbeats, the server should infer that the peer has left the network.
2.4. File Names and Execution
Language |
Client |
Server |
C |
client.c |
server.c |
Java |
Client.java |
Server.java |
Python |
client.py |
server.py |
Both the server and client should accept the following command-line argument:
Both applications should be given the same port argument. During marking, you can assume this to be the case, and that the port argument will be valid.
Upon execution, the server should bind to the UDP port number given as a command-line argument.
Note, you do not need to specify the port to be used by the client to communicate with the server. The client program should allow the operating system to allocate any available UDP port, which the server will learn upon receipt of a message.
Similarly, the TCP port on which each client will listen for peer connections does not need to be specified in advance. Each client can establish a TCP socket, allowing the operating system to allocate any available port, and then communicate the allocated port number to the server. The server can then store this information and share it with other clients as needed to support peer-to-peer filesharing.
The server and all clients will be tested on the same host, so you may hardcode the interface as 127.0.0.1 (localhost). As we’ll be using the loopback interface, you can assume that no UDP packets will be lost, corrupted, or re-ordered “in flight”.
2.5. Application Output
Some examples illustrating client-server interaction are provided in H. Sample Interactions.
Please do not email course staff or post on the forum asking if your output is acceptable. This is not scalable for a course of this size. If you are unsure of your output, then you should follow the example output.
3. Program Design Considerations
3.1. Server Design
While we do not mandate the specifics, it is critical that you invest some time into thinking about the design of your data structures. Examples of state information includes the time when each peer was last active (or the time it will be deemed inactive), the current address of their TCP welcoming socket, the files that are published on the network, and a list of users who have published each of those files.
As you may have learnt in your programming courses, it is not good practice to arbitrarily assume a fixed upper limit on such data structures. Thus, we strongly recommend allocating memory dynamically for all the data structures that are required.
Should you choose to implement a multithreaded server, then you should be particularly careful about how multiple threads will interact with the various data structures.
3.2. Client Design
When a download takes place, in this case with client “B” requesting a file from client “A”, “B” creates a new TCP client socket and initiates a three-way handshake with the welcoming socket of “A”. In this context, “B” can be viewed as the client and “A” as the server in a client-server model.
Once the handshake is complete, a new connection socket will be created at “A”, and the data transfer can commence.
Figure 2: BitTrickle sockets from the example of Figure 1
Of course the peer-to-peer network may be more complex. “A” may be managing any number of connection sockets to support multiple peers that are downloading files simultaneously. Meanwhile “A” should be sending heartbeats periodically to the server and might also be downloading a file itself from another peer in response to a user command. A robust way to achieve this is to use multithreading.
1. To accept and act upon user input.2. To periodically send heartbeat messages to the server via UDP.3. To listen for download requests via the TCP welcoming socket, and, when one is received:a. Launch a short-lived thread with the TCP connection socket to perform the file transfer.
When the client starts up it should create a UDP socket to communicate with the server and a TCP socket to accept peer-to-peer download requests. It could then spin off a new thread to listen for download requests on the TCP socket (thread 3 above). The main thread (thread 1 above) could then initiate the authentication process. At some stage the client will need to send the address of its TCP socket to the server. This could be included as part of the authentication exchange or sent immediately after having successfully authenticated. Once successfully authenticated, the client 10 could spin off a new thread to periodically send heartbeat messages (thread 2 above). The main thread (thread 1 above) could then enter its interactive shell loop, prompting the user for input and executing each command.
3.3. Application Layer Protocol
3.4. Message / Buffer Sizes
You may assume that the payload of UDP-based application messages (e.g. a list of active peers or a list of matching files) does not exceed 1024 bytes. You are free to nominate appropriate buffer sizes for these messages based on the additional overhead of your application layer protocol.
You should not assume that files transferred via TCP can fit within any nominal buffer. The uploading peer may need to repeatedly read a chunk of the file and write it to the socket, and correspondingly, the downloading peer may need to repeatedly read a chunk from the socket and write it to the file.
3.5. Name, Type, and Size of Published Files
You should not assume that files published on BitTrickle are of a particular format or encoding.
They should be read and written in binary mode as raw bytes, rather than in text mode.
You are encouraged to use tools like diff to verify that any received file is an exact duplicate of the original.
4. Report
- Details of which language you have used (e.g., C) and the organisation of your code (Makefile, directories if any, etc.).
- The overall program design, for example, the main components (client, server, helper classes/functions) and how these components interact.11
- Data structure design, for example, any data structures used by the server to maintain state about published files and active peers.
- Application layer protocol message format(s).
- Known limitations, for example, if your program does not work under certain circumstances, then report those circumstances.
- Also indicate any segments of code that you have borrowed from the Web or other sources.
You are free to use C, Java, or Python. Please choose a language with which you are comfortable.
Your submission will be tested on the CSE servers. For this reason, it is critical that your code can compile and run in that environment, using the standard system installations. This is especially important if you plan to develop and test your code on your personal computer.
- C: gcc v12.2
- Java: openjdk v17.0
- Python: python3 v3.11
If your code does not run on the CSE servers, then it cannot be marked, and it will be awarded ZERO.
You may only use the basic socket programming APIs providing in your programming language of choice. You may not use any special ready-to-use libraries or APIs that implement certain functions of the spec for you. Attempting to circumvent the intent of the assignment may similarly result in a mark of ZERO.
If you are unsure about anything, please check with the course staff on the forum.
- This is not a group assignment. You are expected to work on this individually.
- Sample Code: Code snippets are provided on the course website in all 3 programming languages. These snippets provide examples of socket programming with both TCP and UDP, and multithreading. You are not required to use any of the provided snippets, but you are welcome to adapt them as you see fit.
- Programming Tutorial: We will run programming tutorials, for all 3 programming languages, during regular lab times in Week 7. These will provide further discussion and practice around socket programming and multithreading. A schedule for these sessions will be announced no later than Week 6.
- Assignment Help Sessions: We will run additional consultations, for all 3 programming languages, through Week 7 to 9, to assist with assignment related questions. A schedule will be posted on the assignment page of the course website no later than Week 6. Please note, these sessions are not a forum for tutors to debug your code.
- Backup and Versioning: We strongly recommend you back-up your programs frequently. CSE backs up all user accounts nightly. If you are developing code on your personal machine, it is strongly recommended that you undertake daily backups. We also recommend using a good versioning system so that you can roll back and recover from any inadvertent changes. There are many services available for this, which are easy to use. We will not entertain any requests for special consideration due to issues related to computer failure, lost files, etc.13
- Debugging: When implementing a complex assignment such as this, there are bound to be errors in your code. We strongly encourage that you follow a systematic approach to debugging. If you are using an IDE for development, then it is bound to have debugging functionalities. Alternatively, you could use a command line debugger such as pbd (Python), jdb (Java) or gdb (C). Use one of these tools to step through your code, create break points, observe the values of relevant variables and messages exchanged, etc. Proceed step by step, check and eliminate the possible causes until you find the underlying issue. Note that, we won't be able to debug your code on the course forum or in the help sessions.
- It is imperative that you rigorously test your code to ensure that all possible (and logical) interactions can be correctly executed. Test, test, and test.
- You are encouraged to use the course discussion forum to ask questions and to discuss different approaches to solve the problem. However, you must not post your solution or any code fragments on the forum, or on any other public medium.
Please ensure that you use the mandated file names of report.pdf and for the entry point of each application. These are:
Language |
Client |
Server |
C |
client.c |
server.c |
Java |
Client.java |
Server.java |
Python |
client.py |
server.py |
Language |
Client |
Server |
C |
client |
server |
Java |
Client.class |
Server.class |
You should not submit a credentials.txt, any build artefacts, or any files used to test file transfer between peers.
However, if your submission does rely on some directory structure, then you must first tar the parent directory as assign.tar. For example, assuming a directory assign contains all the relevant files and sub-directories. Open a terminal and navigate to the parent directory of assign, then:
Upon running give, ensure that your submission is accepted. You may submit often. Only your last submission will be marked.
Emailing your code to course staff will not be considered as a submission.
Important: It is your responsibility to ensure that your submission is accepted, and that your submission is what you intend to have assessed. No exceptions.
D. Late Submission Policy
Late submissions will incur a 5% per day penalty, for up to 5 days, calculated on the achieved mark.
Each day starts from the deadline and accrues every 24 hours.
For example, an assignment otherwise assessed as 12/20, submitted 49 hours late, will incur a 3 day
Submissions after 5 days from the deadline will not be accepted unless an extension has been granted, as detailed in E. Special Consideration and Equitable Learning Services.
E. Special Consideration and Equitable Learning Services
Students who are registered with Equitable Learning Services must email [email protected] to request any adjustments based on their Equitable Learning Plan.
Any requested and approved extensions will defer late penalties and submission closure. For example, a student who has been approved for a 3 day extension, will not incur any late penalties until 3 days after the standard deadline, and will be able to submit up to 8 days after the standard deadline.
F. Plagiarism
We are aware that a lot of learning takes place in student conversations, and don't wish to discourage those. However, it is important, for both those helping others and those being helped, not to provide or accept any programming code in writing, as this is likely to be used exactly as is, and lead to plagiarism penalties for both the supplier and the copier of the code. Write something on a piece of paper, by all means, but tear it up/take it away when the discussion is over.
It is OK to borrow short snippets of sample socket code out on the Web and in books. You must, however, acknowledge the source of any borrowed code. This means providing a reference to a book or a URL (as comments) where the code appears. Also indicate in your report the portions of your code that were borrowed. Explain any modifications you have made (if any) to the borrowed code.
Generative AI Tools: It is prohibited to use any software or service to search for or generate information or answers. If its use is detected, it will be regarded as serious academic misconduct and subject to the standard penalties, which may include 00FL, suspension and exclusion.
G. Marking Policy
G.1. Preliminary Checks
We will perform both automated and manual checks to assess:
- That the submitted code is original. See F. Plagiarism.
- That the submitted code can compile and run in the standard CSE lab environment, and only uses permitted features. See A. Languages and Permitted Features.
- That the submitted code utilises UDP for all client-server communications and TCP for all peer-to-peer communications.
Failing any of the above will likely result in a mark of ZERO, and in the case of plagiarism, possibly further disciplinary action.
G.2. Marking Process
A typical marking session will last for approximately 15 minutes during which we will initiate at most 5 clients. However, you should not hard code any specific limits in your programs. We will be testing under typical usage scenarios for the functionality described in the Assignment Specification.
We won’t be testing your code under very complex scenarios or extreme edge cases.16
G.3. Marking Rubric
Functionality |
Marks |
Authentication (see 2.1. Authentication) |
2 |
Heartbeat mechanism (see 2.2. Heartbeat Mechanism) |
1 |
List active peers (see 2.3.2. lap) |
2 |
Publish a file (see 2.3.4. pub <filename>) |
1 |
List published files (see 2.3.3. lpf) |
2 |
Search for files (see 2.3.5. sch <substring>) |
2 |
Download a file (see 2.3.1. get <filename>) |
6 |
Unpublish a file (see 2.3.6. unp <filename>) |
1 |
Exit (see 2.3.7. xit) |
1 |
Report (see 4. Report) |
1 |
Properly documented and commented code |
1 |
Total Marks |
20 |
- CSE C Coding Style Guide
- Google Java Style Guide
- PEP 8 - Style Guide for Python Code
- $ represents the terminal prompt.
- > represents the client prompt.
- … represents a section of output during which there was no user activity, and the server was only logging heartbeats, that has been removed for clarity.
- The actual terminal windows contain no blank lines. Blank cells have been added to the sample interactions to provide some indication of timing alignment between terminal windows, with file download durations also exaggerated relative to the server log.
- The first two fields of the server log are the time, to millisecond precision, and client port.
5 directories, 6 files
This directory contains our client and server code, and four sub-directories. The server sub-directory will be the working directory of the server and contains the credentials file. The hans, vader, and yoda sub-directories will be the working directories of the three clients we will launch, each initially containing zero or more files for the user to share. The server and all clients will be executed in separate terminals, each within their own working directory. The server will be executed first, before any clients.
At the end of the sample interactions the directory assign will be structured as follows:
We can confirm that the downloaded files are exact duplicates using diff: