예제 #1
0
bool AdlMetaEngine::addFileProps(const FileMap &allFiles, Common::String fname, FilePropertiesMap &filePropsMap) const {
	if (filePropsMap.contains(fname))
		return true;

	if (!allFiles.contains(fname))
		return false;

	FileProperties fileProps;
	fileProps.size = computeMD5(allFiles[fname], fileProps.md5, 16384);

	if (fileProps.size != -1) {
		debug(3, "> '%s': '%s'", fname.c_str(), fileProps.md5.c_str());
		filePropsMap[fname] = fileProps;
	}

	return true;
}
예제 #2
0
/**
 * When client.out is executed, the client will operate in one of two modes.
 * In SEED mode, the client first connects to the tracker server and creates a tracker file. It spins of a thread to accept and serve connections (client_handler()), and then updates the tracker server every \a server_update_frequency seconds with new chunks that it is sharing.
 * In download mode, the client contacts the server every 5 seconds, looking to see if anyone is currently sharing "picture-wallpaper.jpg". Once the server responds with this information, the client downloads the "picture-wallpaper.jpg.track " tracker file from the server, and spins off threads to download the image.
 *
 */
int main(int argc, const char* argv[])
{
	/**
	 * First checks to see if mode, seed_port, client_i, and server_update_frequency were passed in as parameters.
	 * If no parameters were passed, readConfig() is called, and a default values are assigned.
	 */
	if (argc < 5)
	{
		readConfig();
	}
	else
	{
		server_port = 3457;
		mode = atoi(argv[1]);
		seed_port = atoi(argv[2]);
		client_i = atoi(argv[3]);
		server_update_frequency = atoi(argv[4]);
	}

	/* Specifies address: Where we are connecting our socket. */
	struct sockaddr_in server_addr = { AF_INET, htons( server_port ) };
	struct hostent *hp;
	
	/* A buffer for temporarily storing text used in main. */
	char buf[CHUNK_SIZE];

	/** Get the IP address of the tracker server.*/
	if((hp = gethostbyname("localhost")) == NULL)
	{
		printf("Error: Unknown Host");
		exit(1);
	}
	bcopy( hp->h_addr_list[0], (char*)&server_addr.sin_addr, hp->h_length );

	/** Initialize the client array so each element is marked as unused. */
	setUpPeerArray();
	
	if (mode == SEED)
	{
		/** Initialize a TCP connection to the tracker server. */
		struct sockaddr_in server_addr = { AF_INET, htons( server_port ) };
		
		if( ( server_sock = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )
		{
			perror( "Error: socket failed" );
			exit( 1 );
		}

		/** Connect to the server.
		 * Now when we need to communicate to the server, we do it over "server_sock".
		*/
		if (connect( server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr) ) == -1 )
		{
			perror( "Error: Connection Issue" );
			exit(1);
		}
		
		memset(buf, '\0', sizeof(buf));
		
		/** Calculate the MD5 of the picture file we will be sharing. */
		sprintf(buf, "test_clients/client_%d/picture-wallpaper.jpg", client_i);
		char *md5 = computeMD5(buf);
		/** Contact the tracker server, and try to create a tracker file. */
		sprintf(buf, "<createtracker picture-wallpaper.jpg 35738 img %s localhost %d>", md5, seed_port); 
		write(server_sock, buf , strlen(buf));
		free(md5);
		
		/** Spin off a single thread that will accept connections, and share chunks. */
		/* We use the 0th element of the peers array since we only need 1 thread to upload (as per Final Demo requirement. */
		if (pthread_create(&(peers[0].m_thread), NULL, &client_handler, &(client_i)) != 0)
		{
			printf("Error Creating Thread\n");
			exit(1);
		}

		/* Clocks used to wait a predetermined amount of time between contacting the server for a list of tracker files.*/
		clock_t elapsed_time, start = clock();
		/* The initial lower bound of the segment percentage we are sharing. (ie 21% for client_i = 1) */
		int percentage = ((client_i == 1)? (0) : ((client_i * 20) - 19));
		int increment, segment_num = 0;
		/* The client shares in 5% increments. 20 / 5 = 4. So we will increment our percentage 4 times. */
		while (segment_num < 4)
		{
			elapsed_time = clock() - start;
			/* If it has been so many seconds... */
			if (((float)elapsed_time/CLOCKS_PER_SEC) >= server_update_frequency)
			{
				if((server_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
				{
					perror( "Error: socket failed" );
					exit( 1 );
				}
				/* Reconnect the the tracker server. */
				if (connect( server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr) ) == -1 )
				{
					perror( "Error: Connection Issue" );
					exit(1);
				}
				increment = (percentage == 0)? (5) : (4);			
				
				printf("I am client_%d, and I am advertising the following chunk of the file: %d%% to %d%%.\n", client_i, percentage, percentage + increment);

				/* Update the server, letting it know that we are now sharing an additional 5% of the file. If we had more time, we would have calculated the actual start and end bytes. */
				sprintf(buf, "<updatetracker picture-wallpaper.jpg %d %d localhost %d>", percentage /*start byte*/, percentage + increment /*end byte*/, seed_port);
				write(server_sock, buf , strlen(buf));
				
				/**Increment the percentage of the file we are sharing. */ 
				(percentage == 0)? (percentage+=6) : (percentage+=5);
				segment_num++;
				
				start = clock();
			}
		}
	}
	
	/* When foundPic = 1, this means that the server has responded to the <REQ LIST> command indicating that someone is sharing "picture-wallpaper.jpg"
	   Every 5 seconds, the client will send the <REQ LIST> command and check the servers response. Once somone is sharing the file we want, foundPic = 1.*/
	int foundPic = 0;
	int sent;
	/**
	 * When presenting in DOWNLOAD mode, the client will automatically contact the tracker server every 5 seconds until someone is sharing the picture-wallpaper.jpg.
	 * The client will then call the <GET> command, download the tracker file from the server, and spin off a download thread.
	 * The client will then allow the user to input commands from the keyboard until the client is closed.
	 */
	if (mode == DOWNLOAD)
	{
		while (1)
		{
			/* Once we begin downloading the picture, we will allow the user to input commands. */
			if (foundPic == 1 /* && donwload_finish == false*/)
			{
				fgets(buf, sizeof(buf), stdin);
			}
			else
			{
				/* Wait 5 seconds. */
				clock_t elapsed_time, start = clock();
				do
				{
					elapsed_time = clock() - start;
				} while (((float)elapsed_time/CLOCKS_PER_SEC) < 5);
			}
			/* For presenting mode, the <REQ LIST> command will automatically be called (the foundPic == 0 will always be evaluated to true). */
			if ((strncmp(buf, "<REQ LIST>", strlen("<REQ LIST>")) == 0) || foundPic == 0)
			{
				/* create a socket */
				/* internet stream socket, TCP */
				if( ( server_sock = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )
				{
					perror( "Error: socket failed" );
					exit( 1 );
				}

				/* connect to the server */
				if (connect( server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr) ) == -1 )
				{
					perror( "Error: Connection Issue" );
					exit(1);
				}
			
				/* Send the server the <REQ LIST> command. */
				write(server_sock, "<REQ LIST>", strlen("<REQ LIST>"));
				memset(buf, '\0', sizeof(buf));
				while((sent = read(server_sock, buf, sizeof(buf))) > 0)
				{
					/* Search the server's message for the picture-wallpaper tracker file. */
					if (strstr(buf, "picture-wallpaper.jpg") != NULL)
					{
						/*Once we find it, set foundPic to 1 to allow keyboard input after the download has begun. */
						foundPic = 1;
					}
					printf("%s", buf);
					memset(buf, '\0', sizeof(buf));
				}
				
				/* Since buf now contains a <GET> statement, the <GET> command should be invoked below. */
				if (foundPic == 1)
				{
					strcpy(buf, "<GET picture-wallpaper.jpg.track>");
				}
			}
			if (strncmp(buf, "<createtracker", strlen("<createtracker")) == 0)
			{		
				if( ( server_sock = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )
				{
					perror( "Error: socket failed" );
					exit( 1 );
				}
				if (connect( server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr) ) == -1 )
				{
					perror( "Error: Connection Issue" );
					exit(1);
				}
				
				/* Send the server the <createtracker> command. */
				write(server_sock, buf, strlen(buf));
				memset(buf, '\0', sizeof(buf));
				while((sent = read(server_sock, buf, sizeof(buf))) > 0)
				{
					printf("%s", buf);
				}
			}
			if (strncmp(buf, "<updatetracker", strlen("<updatetracker")) == 0)
			{
				if( ( server_sock = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )
				{
					perror( "Error: socket failed" );
					exit( 1 );
				}
				if (connect( server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr) ) == -1 )
				{
					perror( "Error: Connection Issue" );
					exit(1);
				}
			
				write(server_sock, buf, strlen(buf));
				memset(buf, '\0', sizeof(buf));
				while((sent = read(server_sock, buf, sizeof(buf))) > 0)
				{
					printf("%s", buf);
				}
				printf("\n");
			}
			/* When presenting, this code will automatically be executed once someone is sharing the picture-wallpaper.jpg file. */
			if (strncmp(buf, "<GET", strlen("<GET")) == 0)
			{
				FILE *file;
				char tokenize[CHUNK_SIZE], filename[CHUNK_SIZE];
				char *line;
				if( ( server_sock = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )
				{
					perror( "Error: socket failed" );
					exit( 1 );
				}
				if (connect( server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr) ) == -1 )
				{
					perror( "Error: Connection Issue" );
					exit(1);
				}
			
				/* Send the tracker server the command. */
				write(server_sock, buf, strlen(buf));
				
				strcpy(tokenize, buf);
				/*Get the tracker filename*/
				line = strtok(tokenize, " ");
				line  = strtok(NULL, ">");
				strcpy(filename, line);
				
				/* Create an empty file to save the tracker file in. */
				file = fopen(filename, "wb");

				memset(buf, '\0', sizeof(buf));
				while((sent = read(server_sock, buf, sizeof(buf))) > 0)
				{
					/* Save the tracker file (sent from server). */
					fwrite(buf, sizeof(char), strlen(buf), file);
					memset(buf, '\0', sizeof(buf));
				}
				
				fclose(file);
				
				/* Spin off 5 downloads thread. */
				int i;
				for (i = 0; i < 1; i++) /* For debugging purposes, we only spin off 1 thread. */
				{
					if (pthread_create(&(peers[i].m_thread), NULL, &download, &(peers[i].m_index)) != 0)
					{
						perror("Error creating download thread");
					}
				}
			}
			
			/*
			if (download_finish == true)
			{
				//call xiao's appendSegment() function too piece together everything
			}
			*/
			close(server_sock);
		}
	}
	
	
	int i;
	/** Close the program once all threads have completed their work (seeding or downloading). */
	for (i = 0; i < MAX_CLIENT; i++)
	{
		pthread_join(peers[i].m_thread, NULL);
	}

	return 0;
}
예제 #3
0
void *client_handler(void * index)
{
	/* Dereference the index passed as a parameter by the pthread_create() function */
	int client_index = *((int *) index);
	
	/* Clear the buffer of any data used by a previous peer in the same index of the clients array. */
	memset(clients[client_index].m_buf, '\0', sizeof(clients[client_index].m_buf));
	
	/**
	 * Read data from the peer's socket, store it in m_buf.
	 * Compare the string stored in m_buf to see if it is any of the four commands.
	 * And then serve the peer.
	 */
	if (read(clients[client_index].m_peer_socket , clients[client_index].m_buf, CHUNK_SIZE) > 0)
	{
		/** <b>CREATETRACKER Command</b> */
		if (strncmp(clients[client_index].m_buf, "<createtracker", strlen("<createtracker")) == 0)
		{
			/* First check if the client send the correct number of arguments */
			int num_arg = 0;
			char countArgs[CHUNK_SIZE];
			char *numArgCheck;
			
			stpcpy(countArgs, clients[client_index].m_buf);
			/* Each argument/param is seperated with a space. */
			numArgCheck = strtok(countArgs, " ");
			while (numArgCheck != NULL)
			{
				/* For each string of text separated by a space, or delimited with a new line, 
				 * increment num_arg */
				num_arg = num_arg + 1;
				numArgCheck = strtok(NULL, " \n");
			}
			/** If client did not send the correct number of arguments, send a "createtracker fail" protocol message. */
			if (num_arg != 7)
			{
				write(clients[client_index].m_peer_socket, "<createtracker fail>\n", strlen("<createtracker fail>\n"));
			}
			else
			{
				/** The create tracker command is broken up into 7 words:
				 * createtracker, filename, filesize, description, md5, ip, and port.
				 * We are interested in the last 6.
				 */
				char *filename, *filesize, *description, *md5, *ip, *port;
				char tokenize[CHUNK_SIZE];
				
				/* We will copy the buffer into a new array, and parse. */
				stpcpy(tokenize, clients[client_index].m_buf);
				
				/* Get the filename */
				filename = strtok(tokenize, " "); /* Skip over the "createtracker" string. */
				filename = strtok(NULL, " ");
				strcpy(filename, filename);
				
				/* Get filesize */
				filesize= strtok(NULL, " ");
				strcpy(filesize, filesize);
				
				/* Get description */
				description = strtok(NULL, " ");
				strcpy(description, description);
				
				/* Get md5 */
				md5 = strtok(NULL, " ");
				strcpy(md5, md5);
				
				/* Get IP */
				ip = strtok(NULL, " ");
				strcpy(ip, ip);
				
				/* Get port */
				port = strtok(NULL, ">");
				strcpy(port, port);
				
				
				/* We now need to check to see if this tracker file already exists. */
				memset(clients[client_index].m_buf, '\0', sizeof(clients[client_index].m_buf));
				sprintf(clients[client_index].m_buf, "Tracker Files/%s.track", filename);
				
				/* Ensure that only 1 thread is checking the directory at a time */
				pthread_mutex_lock(&file_mutex);
				
				/** If this tracker file already exists, send a "createtracker ferr" protocol message. */
				if (access(clients[client_index].m_buf, F_OK) == 0)
				{
					write(clients[client_index].m_peer_socket, "<createtracker ferr>\n", strlen("<createtracker ferr>\n"));
				}
				/** Otherwise, since this tracker file does not exist, create the tracker file. 
				 * Start by creating an empty file.
				 */
				else if((clients[client_index].m_file = fopen(clients[client_index].m_buf, "w")) != NULL)
				{
					memset(clients[client_index].m_buf, '\0', sizeof(clients[client_index].m_buf));
					
					/* Copy the tracker file contents into the buffer. */
					
					//sprintf(clients[client_index].m_buf, "Filename: %s\nFilesize: %s\nDescription: %s\nMD5: %s\n%s:%s:0:%s:%d", filename, filesize, description, md5, ip, port, filesize,  (unsigned)time(NULL));
					sprintf(clients[client_index].m_buf, "Filename: %s\nFilesize: %s\nDescription: %s\nMD5: %s", filename, filesize, description, md5);
					
					/* Write the buffer contents to the new tracker file. */
					fwrite(clients[client_index].m_buf, sizeof(char), strlen(clients[client_index].m_buf), clients[client_index].m_file);
					/** Let the client know that the creation was successful with a "createtracker succ" protocol message. */
					write(clients[client_index].m_peer_socket, "<createtracker succ>\n", strlen("<createtracker succ>\n"));
					
					/* Close the tracker file. */
					fclose(clients[client_index].m_file);
				}
				/** If there was a problem creating the file, send the user a "createtracker fail" protocol message. */
				else
				{
					perror("can't write file");
					write(clients[client_index].m_peer_socket, "<createtracker fail>\n", strlen("<createtracker fail>\n"));
				}
				/* Unlock the mutex. */
				pthread_mutex_unlock(&file_mutex);
			}
		}
		/** <b>UPDATETRACKER Command</b> */
		else if (strncmp(clients[client_index].m_buf, "<updatetracker", strlen("<updatetracker")) == 0)
		{
			/** The update tracker command is broken up into 6 words:
			 * updatetracker, filename, start byte, end byte, ip, and port.
			 * We are interested in the last 5.
			 */
			char *filename, *start, *end, *ip, *port;
			char tokenize[CHUNK_SIZE];
			
			strcpy(tokenize, clients[client_index].m_buf);
			
			/* Get the filename */
			filename = strtok(tokenize, " ");
			filename = strtok(NULL, " ");
			strcpy(filename, filename);
			
			/* Get the start byte */
			start = strtok(NULL, " ");
			strcpy(start, start);
			
			/* Get the end byte */
			end = strtok(NULL, " ");
			strcpy(end, end);
			
			/* Get IP */
			ip = strtok(NULL, " ");
			strcpy(ip, ip);
			
			/* Get port */
			port = strtok(NULL, ">");
			strcpy(port, port);
			
			/* We now need to check to see if this tracker file already exists. */
			memset(clients[client_index].m_buf, '\0', sizeof(clients[client_index].m_buf));
			sprintf(clients[client_index].m_buf, "Tracker Files/%s.track", filename);
			
			pthread_mutex_lock(&file_mutex);
			
			/** If this tracker file does not exist, send a "createtracker ferr" protocol message. */
			if (access(clients[client_index].m_buf, F_OK) == -1)
			{
				write(clients[client_index].m_peer_socket, "<updatetracker ferr>\n", strlen("<updatetracke ferr>\n"));
			}
			/** Otherwise, append the new chunk data to the end of the tracker file. */
			else
			{
				if((clients[client_index].m_file = fopen(clients[client_index].m_buf, "a")) != NULL)
				{
					/* Copy contents into buffer. */
					sprintf(clients[client_index].m_buf, "\n%s:%s:%s:%s:%d", ip, port, start, end,  (unsigned)time(NULL));
					/* Append the buffer contents to the end of the tracker file. */
					fwrite(clients[client_index].m_buf, sizeof(char), strlen(clients[client_index].m_buf), clients[client_index].m_file);
					/** Let the client know that the update was successful with a "updatetracker succ" protocol message. */
					write(clients[client_index].m_peer_socket, "<updatetracker succ>", strlen("<updatetracker succ>"));
					
					/* Close the tracker file. */
					fclose(clients[client_index].m_file);
				}
				/** If there was a problem updating the file, send the user a "updatetracker fail" protocol message. */
				else
				{
					write(clients[client_index].m_peer_socket, "<updatetracker fail>\n", strlen("<updatetracke fail>\n"));
				}
			}
			/* Unlock the mutex. */
			pthread_mutex_unlock(&file_mutex);
		}
		/** <b>REQ LIST Command</b> */
		else if (strncmp(clients[client_index].m_buf, "<REQ LIST>", strlen("<REQ LIST>")) == 0)
		{
			DIR *tracker_directory;
			struct dirent *individual_file;
			
			pthread_mutex_lock(&file_mutex);
			/** First, opens the "Tracker Files" folder, and counts the number of files. */
			if ((tracker_directory = opendir("Tracker Files")) != NULL)
			{
				int num_files = 0;
				while ((individual_file = readdir(tracker_directory)) != NULL)
				{
					/*readdir returns root directories "." and ".."*/
					/*We need to ignore them*/
					if ((strncmp(individual_file->d_name, ".", 1) != 0) && (strncmp(individual_file->d_name, "..", 2) != 0))
					{
						num_files = num_files + 1;
					}
				}
				if (closedir(tracker_directory) == -1)
				{
					perror("Closing dir error.\n");
				}
				
				/* Send the first line of the LIST response. */
				sprintf(clients[client_index].m_buf, "<REP LIST %d>\n", num_files);
				write(clients[client_index].m_peer_socket, clients[client_index].m_buf, strlen(clients[client_index].m_buf));
			}
			
			/** For each file in the "Tracker Files" folder, stores the tracker file's: Filename, filesize, and md5. */
			if ((tracker_directory = opendir("Tracker Files")) != NULL)
			{
				int num_files = 0;
				while ((individual_file = readdir(tracker_directory)) != NULL)
				{
					/*readdir returns root directories "." and ".."*/
					/*We need to ignore them*/
					if ((strncmp(individual_file->d_name, ".", 1) != 0) && (strncmp(individual_file->d_name, "..", 2) != 0))
					{
						num_files = num_files + 1;
					
						memset(clients[client_index].m_buf, '\0', sizeof(clients[client_index].m_buf));
						char *line = NULL;
						char *filename, *filesize, *md5;
						size_t len = 0;
						
						sprintf(clients[client_index].m_buf, "Tracker Files/%s", individual_file->d_name);
						
						if((clients[client_index].m_file = fopen(clients[client_index].m_buf, "r")) != NULL)
						{
							memset(clients[client_index].m_buf, '\0', sizeof(clients[client_index].m_buf));
							
							sprintf(clients[client_index].m_buf, "<%d",num_files);
						
							/* Get the filename */
							getline(&line, &len, clients[client_index].m_file);
							filename = strtok(line, ": ");
							filename = strtok(NULL, "\n");
							strcat(clients[client_index].m_buf, filename);
							
							/* Get the filesize */
							getline(&line, &len, clients[client_index].m_file);
							filesize = strtok(line, ": ");
							filesize = strtok(NULL, "\n");
							strcat(clients[client_index].m_buf, filesize);
							
							/* Skip over the file description line */
							getline(&line, &len, clients[client_index].m_file);
							
							/* Get the md5 */
							getline(&line, &len, clients[client_index].m_file);
							md5 = strtok(line, ": ");
							md5 = strtok(NULL, "\n");
							strcat(clients[client_index].m_buf, md5);
							strcat(clients[client_index].m_buf, ">\n");
							
							fclose(clients[client_index].m_file);
							free(line);
							
							/** Sends each tracker file info, indexed by a number. */
							write(clients[client_index].m_peer_socket, clients[client_index].m_buf, strlen(clients[client_index].m_buf));
						}
					}
				}
				memset(clients[client_index].m_buf, '\0', sizeof(clients[client_index].m_buf));
				strcpy(clients[client_index].m_buf, "<REP LIST END>\n");
				/* Send the footer of the "REQ" protocol message */
				write(clients[client_index].m_peer_socket, clients[client_index].m_buf, strlen(clients[client_index].m_buf));
				
				if (closedir(tracker_directory) == -1)
				{
					perror("Closing dir error.\n");
				}
			}
			pthread_mutex_unlock(&file_mutex);
		}
		/** <b>GET Command</b> */
		else if (strncmp(clients[client_index].m_buf, "<GET", strlen("<GET")) == 0)
		{
			char *tracker_filename;
			char parseFileName[CHUNK_SIZE];
			
			/* Get the filename.track */
			stpcpy(parseFileName, clients[client_index].m_buf);
			tracker_filename = strtok(parseFileName, " ");
			tracker_filename = strtok(NULL, ">");
			
			sprintf(clients[client_index].m_buf, "Tracker Files/%s", tracker_filename);
			sprintf(tracker_filename, "%s", clients[client_index].m_buf);
			
			pthread_mutex_lock(&file_mutex);
			/** First, the server checks to make sure that the requested tracker file already exists. */
			if (access(clients[client_index].m_buf, F_OK) == 0) /* If that file exists..... */
			{
				/** Next, it opens the file, and copies it's contents. */
				if((clients[client_index].m_file = fopen(tracker_filename, "r")) != NULL)
				{
				
					/* ADD ME BACK LATER
					//write(clients[client_index].m_peer_socket, "<REP GET BEGIN>\n", strlen("<REP GET BEGIN>\n"));					*
					*/
					
					memset(clients[client_index].m_buf, '\0', sizeof(clients[client_index].m_buf));
					int read;
					/** It then sends the peer the tracker file, copied into a buffer. */
					while((read = fread(clients[client_index].m_buf, sizeof(char), CHUNK_SIZE, clients[client_index].m_file)) > 0)
					{
						write(clients[client_index].m_peer_socket, clients[client_index].m_buf, read);
						memset(clients[client_index].m_buf, '\0', sizeof(clients[client_index].m_buf)); 
					}
					
					/**Finally, it includes the md5 sum of the tracker file itself, and appends it to the end of the "GET" protocol footer. */
					char * md5_string;
					md5_string = computeMD5(tracker_filename);
					
					memset(clients[client_index].m_buf, '\0', sizeof(clients[client_index].m_buf));
					/* ADD ME BACK LATER
					sprintf(clients[client_index].m_buf, "\n<REP GET END %s>", md5_string);
					*/
					free(md5_string);
					
					/* ADD ME BACK LATER
					write(clients[client_index].m_peer_socket, clients[client_index].m_buf, strlen(clients[client_index].m_buf));
					*/
				}
				/** If the tracker file could not be opened, the server sends the peer a "GET invalid" protocol error message. */
				else
				{
					write(clients[client_index].m_peer_socket, "<GET invalid>", strlen("<GET invalid>"));
				}
			}
			/** If the file does not exist, the server sends the peer a "GET invalid" protocol error message. */
			else
			{
				write(clients[client_index].m_peer_socket, "<GET invalid>", strlen("<GET invalid>"));
			}
			pthread_mutex_unlock(&file_mutex);
		}
	}
	
	/** <b> Closing the connection to the peer.</b> */
	/** 
	 * Once the peer's request has been handled, the server closes that socket, 
	 * indicates that there is a new opening in the \a client array, 
	 * and ends the thread. */
	if (close(clients[client_index].m_peer_socket) != 0)
	{
		perror("Closing socket issue");
	}
	/* Indicate that this element of the clients array is free to use. */
	clients[client_index].m_peer_socket = -1;
	
	/* End the thread.
	 * In this context, thread clean-up behaviour using pthread_cancel() and pthread_exit() are the same. */
	if (pthread_cancel(clients[client_index].m_thread) != 0)
	{
		perror("Ending thread issue");
		exit(1);
	}
	
	//return;
}