A WIP implementation of a Peer to Peer File Sharing Network in C++i
Currently: Able to obtain clients which have file pieces, and able to connect to these clients over multiple threads to bring in the file pieces. However, there's a bug in which the last part of the image is not obtained. This is being investigated
It is in a very early development stage. The aim is to create a Peer to Peer file sharing network that works on the following basis:
-
The Server is just a bookkeeper that keeps a track of which clients are there on the network, and what pieces of files they have. No file is actually stored on the main server
-
The Clients are simultaneously clients and servers. In this model, the client can both send and recieve pieces from others on the network.
The protocol is currently in a very rudimentary state. The basic idea is that:
-
All protocol commands are initiated by an integer that selects a command. The following commands are available as of now: (a). 0: Handshake (Register user on the server) (b). 1: File Info Registration (Inform the server that a file is present on a client) (c). 2: File Request (Ask for a file)
-
Once the command is sent, the client is expected to send data pertaining to that command. There is no error-checking or confirmation of packet delivery as of now, but it is planned. One thing to keep in mind is that arrays inside structures cannot be sent directly due to the way writes are handled by the OS. You need to go to every pointer and send the data at that address.
This is because write directly writes the bytes. So if you have:
struct A{
int var;
int* p;
}
And you issue the command write(file_fd, &A, sizeof(A)). On the other end, you'll have a struct with var holding the value of the var in the struct you sent, and p having the address held by p when you sent A(IMPORTANT). Since for the pointer you're essentially sending a memory address to a different machine, you won't get the intended behavior. This is why you have to send A, then p separately (Yes, this is a bit wasteful).
The Handshake Structure consists of a 128 byte ID that is automatically generated by a helper function. Each user is expected to have a unique ID.
It also has a port field that you must populate with the PORT you're listening on. As mentioned above, you'll first be sending the Handshake struct, then the ID.
To inform to the server that you have a file available, you have a FileInfo struct. It currently just contains an integer ID that YOU have to generate.
This is perhaps the most complicated part of the whole process. For issuing a FileRequest, you have a request structure that has an integer file id.
The server then populates a vector with the IP addresses of the clients that have the file. A readVector function is provided, which should be used to read the vector.
Then the client connects to these clients on multiple threads, fetching various pieces of the file. Since the pieces would be appended in a vector, to prevent race conditions, this part should be locked by a mutex.
Once these pieces are obtained, a function is provided to reconstruct the file from the pieces. Right now, the name of the output file is hardcoded, but that is a trivial change. The function automatically handles the sorting of file pieces, but has no error checking to ensure that ALL the pieces are actually present before stiching them together.
- Server distributes pieces to files on a demand basis, and keeps hashes to ensure security
- Server ensures that all file pieces are available on the Network, and keeps multiple copies across multiple clients
Depends on BSD sockets