public Tuple<string, List<string>> ChunksUpto(string str, int ChunkSize)
        {
            // Get the hash of the string
            var fileDictObject = new ObjectForFiledict();
            StringBuilder sb = new StringBuilder();
            byte[] fileBytes = Encoding.UTF8.GetBytes(str);
            using (var cryptoProvider = new SHA1CryptoServiceProvider())
            {
                sb.Append(BitConverter.ToString(cryptoProvider.ComputeHash(fileBytes)));
            }

                List<string> result = new List<string>();
            for (int i = 0; i < str.Length; i += ChunkSize)
                result.Add(str.Substring(i, Math.Min(ChunkSize, str.Length - i)));
            return new Tuple<string, List<string>>(sb.ToString(),result);
        }
        public Tuple <string, List <string> > ChunksUpto(string str, int ChunkSize)
        {
            // Get the hash of the string
            var           fileDictObject = new ObjectForFiledict();
            StringBuilder sb             = new StringBuilder();

            byte[] fileBytes = Encoding.UTF8.GetBytes(str);
            using (var cryptoProvider = new SHA1CryptoServiceProvider())
            {
                sb.Append(BitConverter.ToString(cryptoProvider.ComputeHash(fileBytes)));
            }

            List <string> result = new List <string>();

            for (int i = 0; i < str.Length; i += ChunkSize)
            {
                result.Add(str.Substring(i, Math.Min(ChunkSize, str.Length - i)));
            }
            return(new Tuple <string, List <string> >(sb.ToString(), result));
        }
Esempio n. 3
0
        private async Task OnTransferAsync(TcpClient tcpClient, StateObject tcpState)
        {
            await Task.Yield();

            using (var networkStream = tcpClient.GetStream())
            {
                var buffer = new byte[8192];

                // Receiving and deserialized the serializable object
                var byteCount = await networkStream.ReadAsync(buffer, 0, buffer.Length);

                if (byteCount > 0)
                {
                    ServerSb.Append(Encoding.UTF8.GetString(buffer, 0, byteCount));
                    var StringMsg = ServerSb.ToString();
                    if (StringMsg.IndexOf("</TcpMsg>") > -1)
                    {
                        var xmlSerializer     = new XmlSerializer(typeof(ServerClientMsg));
                        var ReceivedMsgObject = new ServerClientMsg();
                        using (var textReader = new StringReader(StringMsg))
                        {
                            ReceivedMsgObject = (ServerClientMsg)xmlSerializer.Deserialize(textReader);
                        }

                        // Clear string builder since we are done with it
                        ServerSb.Clear();

                        var MsgObjectToReturn = new ServerClientMsg();

                        // If this thread is for the server
                        if (tcpState.ClientType == false)
                        {
                            MsgObjectToReturn = ServerCreateRly(ReceivedMsgObject);
                        }
                        // If this thread if for the client
                        else
                        {
                            // Now that we have the serializable object, we need to switch through all the commands
                            switch (ReceivedMsgObject.Command)
                            {
                            // Data request command
                            case (int)ServerClientMsg.Commands.DataRq:

                                byte[] file;
                                string hash = string.Empty;
                                //Console.WriteLine("Client Server: received data request for file: {0} segment: {1}", ReceivedMsgObject.NameOfFile,ReceivedMsgObject.SegmentOfFile);

                                string filepath = tcpState.TempFolderPath + @"/" + Path.GetFileNameWithoutExtension(ReceivedMsgObject.NameOfFile);
                                filepath += "_temp" + ReceivedMsgObject.SegmentOfFile + Path.GetExtension(ReceivedMsgObject.NameOfFile);
                                //Console.WriteLine("Client Server: Retreiving file: {0}", filepath);

                                // See if the client's server actually has the file or not
                                if (File.Exists(filepath))
                                {
                                    file = File.ReadAllBytes(filepath);
                                }
                                else
                                {
                                    //Console.WriteLine("Client Server could not find the file {0}", filepath);
                                    file = new byte[2];
                                }

                                // Retrieveing the hash to send back with the data segment
                                foreach (var pair in tcpState.FileDict)
                                {
                                    if (pair.Key == ReceivedMsgObject.NameOfFile)
                                    {
                                        ObjectForFiledict obj = pair.Value;
                                        hash = obj.Hash;
                                        //Console.WriteLine("Client Server: Hash = {0}", hash);
                                        break;
                                    }
                                }

                                MsgObjectToReturn.DataRly(hash, ReceivedMsgObject.SegmentOfFile, file);

                                break;

                            default:
                                Console.WriteLine("Invalid command to the client server");
                                break;
                            }
                        }

                        // At this point, the serializable object should be popululated with the proper command and info
                        StringBuilder SerializedSb = new StringBuilder();

                        using (var stringWriter = new StringWriter())
                        {
                            xmlSerializer.Serialize(stringWriter, MsgObjectToReturn);
                            SerializedSb.Append(stringWriter.ToString());
                        }

                        var serializedString = SerializedSb.ToString();
                        var MsgToSend        = Encoding.UTF8.GetBytes(serializedString);

                        // Sending the serializable response back
                        await networkStream.WriteAsync(MsgToSend, 0, MsgToSend.Length);

                        //Console.WriteLine("[Server] Response has been given");
                    }
                }
            }
        }
Esempio n. 4
0
        // This method is reponsible for getting the all the file segments from the available clients and stitch all the file segments back together
        public async Task GetDownloadFile(StateObject clientState)
        {
            // Requesting the file location file the server
            var getLocationCmd = new ClientPassableObject(clientState);

            getLocationCmd.GetFilesLocation(clientState.FileNameToDownload);
            await ClientStart(getLocationCmd);

            while (getLocationCmd.DoneFlag == false)
            {
                ;
            }

            Console.WriteLine("Client: File: {0} has a length of {1}", clientState.FileNameToDownload, getLocationCmd.FileToDownloadLength);
            for (int i = 0; i < getLocationCmd.AddressAtFile2Download.Count; i++)
            {
                Console.WriteLine("Client: Address: {0}  Port: {1}", getLocationCmd.AddressAtFile2Download[i],
                                  getLocationCmd.PortAtFile2Download[i]);
            }

            var           DataOperator   = new DataSegmentObject();
            var           NoOfSegments   = DataOperator.GetNoOfSegments(getLocationCmd.FileToDownloadLength, clientState.MaxChunkSize);
            List <byte[]> bytesResult    = new List <byte[]>();
            List <int>    ResultSegIndex = new List <int>();
            string        hashResult     = string.Empty;

            for (int i = 0; i < NoOfSegments; i++)
            {
                //Console.WriteLine("Client: requesting File: {0} segment: {1} from {2}  {3}", clientState.FileNameToDownload, i,
                //getLocationCmd.AddressAtFile2Download[0], getLocationCmd.PortAtFile2Download[0]);
                var getFileCmd = new ClientPassableObject(clientState);
                getFileCmd.GetFile(getLocationCmd.AddressAtFile2Download[0], getLocationCmd.PortAtFile2Download[0], clientState.FileNameToDownload, i);
                await ClientStart(getFileCmd);

                while (getFileCmd.DoneFlag == false)
                {
                    ;
                }
                //Console.WriteLine("Client: Received segment {0}", i);
                bytesResult.Add(getFileCmd.ResultFileSegment);
                ResultSegIndex.Add(getFileCmd.ResultFileSegmentNo);
                hashResult = getFileCmd.ResultFileHash;
            }
            Console.WriteLine("Received all segments of the file");

            List <string> AvailableAddresses  = getLocationCmd.AddressAtFile2Download;
            List <int>    AvailablePorts      = getLocationCmd.PortAtFile2Download;
            int           NoOfAvailableClient = AvailableAddresses.Count;


            string      FileToDownload      = getLocationCmd.FileToDownload;
            int         SegmentDone         = 0;
            int         SegmentInTransit    = 0;
            List <bool> BusyClient          = new List <bool>();
            List <Task> task                = new List <Task>();
            List <int>  indexOfTasks        = new List <int>();
            List <ClientPassableObject> cmd = new List <ClientPassableObject>();


            //while (SegmentDone < NoOfSegments)
            //{
            //    for (int q = 0; q < AvailableAddresses.Count; q++)
            //    {
            //        if (SegmentDone < NoOfSegments)
            //        {
            //            var getfileCmd = new ClientPassableObject(clientState);
            //            getfileCmd.GetFile(AvailableAddresses[q], AvailablePorts[q], FileToDownload, SegmentDone);
            //            Console.WriteLine("Requesting segment #{0} from {1}  ,  {2}", SegmentDone + SegmentInTransit, AvailableAddresses[q], AvailablePorts[q]);
            //            task.Add(ClientStart(getfileCmd));
            //            cmd.Add(getfileCmd);
            //            SegmentDone++;
            //            task[0].Wait();
            //        }
            //        else
            //            break;

            //    }
            //    // Wait until all the tasks are complete
            //    while (true)
            //    {
            //        int counter = 0;
            //        foreach (var command in cmd)
            //        {
            //            if (command.DoneFlag)
            //                counter++;
            //        }
            //        if (counter == cmd.Count)
            //            break;
            //    }

            //    for (int k = 0; k < cmd.Count; k++)
            //    {

            //        bytesResult.Add(cmd[k].ResultFileSegment);
            //        ResultSegIndex.Add(cmd[k].ResultFileSegmentNo);
            //        hashResult = cmd[k].ResultFileHash;
            //    }
            //    task.Clear();
            //    indexOfTasks.Clear();
            //    cmd.Clear();
            //}



            //for (int i = 0; i < NoOfAvailableClient; i++)
            //    BusyClient.Add(false);

            //while (SegmentDone < NoOfSegments)
            //{
            //    if ((SegmentInTransit + SegmentDone) <= NoOfSegments)
            //    {
            //        if (BusyClient.IndexOf(false) > -1)
            //        {
            //            int j = BusyClient.IndexOf(false);

            //            var getfileCmd = new ClientPassableObject(clientState);
            //            getfileCmd.GetFile(AvailableAddresses[j], AvailablePorts[j], FileToDownload, SegmentDone + SegmentInTransit);
            //            Console.WriteLine("Requesting segment #{0} from {1}  ,  {2}", SegmentDone + SegmentInTransit, AvailableAddresses[j], AvailablePorts[j]);
            //            task.Add(ClientStart(getfileCmd));
            //            indexOfTasks.Add(j);
            //            BusyClient[j] = true;
            //            cmd.Add(getfileCmd);
            //            SegmentInTransit++;
            //        }
            //        else
            //        {
            //            for (int k = 0; k < indexOfTasks.Count; k++)
            //            {
            //                if (cmd[k].DoneFlag)
            //                {
            //                    bytesResult.Add(cmd[k].ResultFileSegment);
            //                    ResultSegIndex.Add(cmd[k].ResultFileSegmentNo);
            //                    hashResult = cmd[k].ResultFileHash;
            //                    BusyClient[indexOfTasks[k]] = false;

            //                    SegmentDone++;
            //                    SegmentInTransit--;
            //                }
            //            }
            //            for (int f = indexOfTasks.Count -1; f >= 0; f--)
            //            {
            //                if (cmd[f].DoneFlag)
            //                {
            //                    task.RemoveAt(f);
            //                    indexOfTasks.RemoveAt(f);
            //                    cmd.RemoveAt(f);
            //                }

            //            }
            //        }

            //    }

            //}

            // Reordering the info
            List <byte[]> ResultInOrder = new List <byte[]>();

            for (int k = 0; k < bytesResult.Count; k++)
            {
                int indexOfSegment = ResultSegIndex.IndexOf(k);
                ResultInOrder.Add(bytesResult[indexOfSegment]);
            }

            // Combine all the segment and compare the hashcode
            int filesize         = 0;
            int accumulativeSize = 0;

            foreach (var seg in ResultInOrder)
            {
                filesize += seg.Length;
            }
            byte[] wholeFile = new byte[filesize];
            foreach (var seg in ResultInOrder)
            {
                System.Buffer.BlockCopy(seg, 0, wholeFile, accumulativeSize, seg.Length);
                accumulativeSize += seg.Length;
            }

            var dataparser = new DataSegmentObject();

            if (dataparser.getHashAndCompare(wholeFile, hashResult) == true)
            {
                Console.WriteLine("File: {0} is finished. You can find the file in the your desktop.");
                var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"/" + clientState.FileNameToDownload + "new";

                // Writing the whole file to the desktop
                using (var bw = new BinaryWriter(File.Open(path, FileMode.OpenOrCreate)))
                {
                    bw.Write(wholeFile);
                }

                FileInfo f = new FileInfo(path);
                clientState.FilePathsToReg.Clear();
                clientState.FilePathsToRegLength.Clear();
                clientState.FilePathsToReg.Add(path);
                clientState.FilePathsToRegLength.Add(f.Length);
                var uploadcmd = new ClientPassableObject(clientState);
                uploadcmd.RegisterFiles();
                await ClientStart(uploadcmd);

                while (uploadcmd.DoneFlag == false)
                {
                    ;
                }

                var DataParser = new DataSegmentObject();

                // splitting the files up and store it in the temp folder
                DataParser.SplitFile(path, clientState.MaxChunkSize, clientState.TempFolderPath);
                var dictObject = new ObjectForFiledict();
                dictObject.Hash         = DataParser.GetHash(clientState.FilePathsToReg[0]);
                dictObject.NoOfSegments = DataParser.GetNoOfSegments(clientState.FilePathsToRegLength[0], clientState.MaxChunkSize);
                clientState.FileDict.Add(Path.GetFileName(clientState.FilePathsToReg[0]), dictObject);
            }
            else
            {
                Console.WriteLine("One of the file was corrupt. We need to retry");
            }

            commandPrint();
        }
Esempio n. 5
0
        private async Task OnTransferAsync(TcpClient tcpClient, StateObject tcpState)
        {
            await Task.Yield();

            using (var networkStream = tcpClient.GetStream())
            {
                var buffer = new byte[8192];


                var byteCount = await networkStream.ReadAsync(buffer, 0, buffer.Length);

                if (byteCount > 0)
                {
                    ServerSb.Append(Encoding.UTF8.GetString(buffer, 0, byteCount));
                    var StringMsg = ServerSb.ToString();
                    if (StringMsg.IndexOf("</TcpMsg>") > -1)
                    {
                        var xmlSerializer     = new XmlSerializer(typeof(ServerClientMsg));
                        var ReceivedMsgObject = new ServerClientMsg();
                        using (var textReader = new StringReader(StringMsg))
                        {
                            ReceivedMsgObject = (ServerClientMsg)xmlSerializer.Deserialize(textReader);
                        }

                        // Clear string builder since we are done with it
                        ServerSb.Clear();

                        var MsgObjectToReturn = new ServerClientMsg();

                        // If this thread if for the server
                        if (tcpState.ClientType == false)
                        {
                            MsgObjectToReturn = ServerCreateRly(ReceivedMsgObject);
                        }
                        // If this thread if for the client
                        else
                        {
                            Console.WriteLine("client Server received {0} command", ReceivedMsgObject.Command);
                            switch (ReceivedMsgObject.Command)
                            {
                            case (int)ServerClientMsg.Commands.DataRq:

                                string file = string.Empty;
                                string hash = string.Empty;

                                Console.WriteLine("ClientServer received the data request");

                                foreach (var pair in tcpState.FileDict)
                                {
                                    if (pair.Key == ReceivedMsgObject.NameOfFile)
                                    {
                                        ObjectForFiledict resultObj = pair.Value;
                                        file = resultObj.Segments[ReceivedMsgObject.SegmentOfFile];
                                        hash = resultObj.Hash;

                                        if (!file.Any() || String.IsNullOrEmpty(hash))
                                        {
                                            Console.WriteLine("string or hash is empty");
                                        }
                                    }
                                }
                                Console.WriteLine("ClientServer is sending string: {0} \nWith a hash of: {1}", file, hash);
                                MsgObjectToReturn.DataRly(hash, ReceivedMsgObject.SegmentOfFile, file);

                                break;

                            default:
                                Console.WriteLine("Invalid command to the client server");
                                break;
                            }
                        }


                        StringBuilder SerializedSb = new StringBuilder();

                        using (var stringWriter = new StringWriter())
                        {
                            xmlSerializer.Serialize(stringWriter, MsgObjectToReturn);
                            SerializedSb.Append(stringWriter.ToString());
                        }

                        var serializedString = SerializedSb.ToString();
                        var MsgToSend        = Encoding.UTF8.GetBytes(serializedString);
                        await networkStream.WriteAsync(MsgToSend, 0, MsgToSend.Length);

                        //Console.WriteLine("[Server] Response has been given");
                    }
                }
            }
        }
Esempio n. 6
0
        static void Main(string[] args)
        {
            using (var sr = new StreamReader(@"../../Intro.txt"))
            {
                while (!sr.EndOfStream)
                    Console.WriteLine(sr.ReadLine());
            }

            Tuple<string, string> userCommand;

            /************************************************
            *
            *   This block of code is used to instantiate the server
            *
            ************************************************/
            //var tcpServer = new TcpTorrent();
            //var serverState = new StateObject();
            //serverState.ClientType = false;
            //var serverTask = tcpServer.StartListener(serverState);

            //tcpServer.StartListener(serverState).Wait();

            /************************************************
            *
            *   This block of code is used to instantiate the client server
            *
            ************************************************/
            StateObject clientState = new StateObject();
            var clientServer = new TcpTorrent();
            clientState.Address = "127.0.0.1" ;
            //clientState.Address = clientServer.GetLocalIPAddress();
            clientState.Port = clientServer.GetOpenPort();
            Console.WriteLine("Creating Client's server on Address: {0} , and Port: {1}", clientState.Address, clientState.Port);
            var task = clientServer.StartListener(clientState);

            // Creating a temp location to store all the temporary files
            var random = new Random();
            clientState.TempFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"/Temp" + random.Next(1, 10);
            if (!Directory.Exists(clientState.TempFolderPath))
            {
                Console.WriteLine("Client: Creating directory at {0}", clientState.TempFolderPath);
                Directory.CreateDirectory(clientState.TempFolderPath);
            }
            else
            {
                clientState.TempFolderPath += random.Next(1, 10);
                Console.WriteLine("Client: Creating directory at {0}", clientState.TempFolderPath);
                Directory.CreateDirectory(clientState.TempFolderPath);
            }

            commandPrint();

            while (true)
            {
                Thread.Sleep(200);
                userCommand = getCommand();

                // Switching through all the user's input
                switch (userCommand.Item1)
                {
                    case "LISTUPLOADABLES":
                        // Clearing the previous file paths since we are repopulating it
                        clientState.UploadableFilePath.Clear();
                        clientState.UploadableFileSize.Clear();

                        // Displaying all the files that are in the desktop folder
                        string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                        int i = 1;
                        Console.WriteLine("\nThe following files are available for download");
                        foreach (var file in Directory.GetFiles(path))
                        {
                            // Only present the file if it hasn't already been added
                            if (!clientState.FileDict.ContainsKey(Path.GetFileName(file)))
                            {
                                FileInfo f = new FileInfo(file);
                                Console.WriteLine("{0}) {1}", i, Path.GetFileName(file));
                                clientState.UploadableFilePath.Add(file);

                                clientState.UploadableFileSize.Add(f.Length);
                            }
                            i++;
                        }
                        commandPrint();
                        break;

                    case "UPLOAD":

                        Tuple<bool, string> validCheck = IsValidInput(userCommand.Item2, clientState.UploadableFilePath.Count);

                        // If any of the value in the previous loop was invalid, we need to break out of this case.
                        if (validCheck.Item1 == false)
                        {
                            Console.WriteLine(validCheck.Item2);
                            commandPrint();
                            break;
                        }

                        // Now what we know that the user's inputs are valid, we need to store the path of the files that the user wants to upload

                        // Clearing the previous FilestoREg list because we have a new list.
                        clientState.FilePathsToReg.Clear();
                        clientState.FilePathsToRegLength.Clear();
                        foreach (string item in userCommand.Item2.Split(','))
                        {
                            clientState.FilePathsToReg.Add(clientState.UploadableFilePath[Convert.ToInt32(item) - 1]);
                            clientState.FilePathsToRegLength.Add(clientState.UploadableFileSize[Convert.ToInt32(item) - 1]);
                        }

                        // creating a new tcp client with the command to register the files that the user had selected
                        var uploadcmd = new ClientPassableObject(clientState);
                        uploadcmd.RegisterFiles();
                        var uploadclient = new TcpTorrent();
                        var clienttask = uploadclient.ClientStart(uploadcmd);

                        while (uploadcmd.DoneFlag == false) ;

                        // Now that we recieved upload on which file can be uploaded, we need to split the files up into segments and store it in the temp folder
                        for (int j = 0; j < uploadcmd.FilesRegSuccessCount.Count; j++)
                        {
                            if (uploadcmd.FilesRegSuccessCount[j] == true)
                            {

                                // Only do something if we don't already have the file in storage.
                                if (!clientState.FileDict.ContainsKey(Path.GetFileName(clientState.FilePathsToReg[j])))
                                {
                                    var DataParser = new DataSegmentObject();

                                    // splitting the files up and store it in the temp folder
                                    DataParser.SplitFile(clientState.FilePathsToReg[j], clientState.MaxChunkSize, clientState.TempFolderPath);
                                    var dictObject = new ObjectForFiledict();
                                    dictObject.Hash = DataParser.GetHash(clientState.FilePathsToReg[j]);
                                    dictObject.NoOfSegments = DataParser.GetNoOfSegments(clientState.FilePathsToRegLength[j], clientState.MaxChunkSize);

                                    Console.WriteLine("Client: splitting file: {0} of length {1} to {2} segments",
                                    clientState.FilePathsToReg[j], clientState.FilePathsToRegLength[j], dictObject.NoOfSegments);

                                    clientState.FileDict.Add(Path.GetFileName(clientState.FilePathsToReg[j]), dictObject);
                                }
                                else
                                    Console.WriteLine("Client: The file already exist in the dictionary. Do not add");
                            }

                        }

                        commandPrint();

                        break;

                    case "LISTDOWNLOADABLES":

                        // Creating a new tcp client that will get all the downloadable files
                        var printcmd = new ClientPassableObject(clientState);
                        printcmd.PrintDownloadable();
                        var printListclient = new TcpTorrent();
                        var printTask = printListclient.ClientStart(printcmd);

                        while (printcmd.DoneFlag == false) ;

                        clientState.DownloadableFileName = printcmd.DownloadableFiles;
                        clientState.DownloadableFileSize = printcmd.DownloadableFilesLength;
                        commandPrint();

                        break;

                    case "DOWNLOAD":
                        Tuple<bool, string> downloadValidCheck = IsValidInput(userCommand.Item2, clientState.DownloadableFileName.Count);

                        // If any of the value in the previous loop was invalid, we need to break out of this case.
                        if (downloadValidCheck.Item1 == false)
                        {
                            Console.WriteLine(downloadValidCheck.Item2);
                            commandPrint();
                            break;
                        }
                        // We are only going to allow one file to be download at a time
                        if (userCommand.Item2.Split(',').Length > 1)
                        {
                            Console.WriteLine("/nYou can only select one download file at a time");
                            break;
                        }

                        // Clearing the previous FilestoREg list because we have a new list.
                        clientState.FileNameToDownload = string.Empty;
                        clientState.FileNameToDownloadLength = 0;

                        clientState.FileNameToDownload = clientState.DownloadableFileName[Convert.ToInt32(userCommand.Item2) - 1];
                        clientState.FileNameToDownloadLength = clientState.DownloadableFileSize[Convert.ToInt32(userCommand.Item2) - 1];

                        // Creating a new TCP client that will download the file from the other client
                        var downloadClient = new TcpTorrent();
                        var downloadTask = downloadClient.GetDownloadFile(clientState);
                        Thread.Sleep(2000);
                        break;

                    case "LEAVE":

                        // createing a new tcp client that will request to leave
                        var leaveCmd = new ClientPassableObject(clientState);
                        leaveCmd.LeaveRequest();
                        var leaveClient = new TcpTorrent();
                        //Console.WriteLine("Creating leave task");
                        var leaveTask = leaveClient.ClientStart(leaveCmd);
                        while (leaveCmd.DoneFlag == false) ;

                        if (Directory.Exists(clientState.TempFolderPath))
                        {
                            Console.WriteLine("Client: deleting directory at {0}", clientState.TempFolderPath);
                            Directory.Delete(clientState.TempFolderPath, true);
                        }
                        else
                            Console.WriteLine("Client: Directory to delete doesn't exist");

                        Console.ReadKey();
                        Environment.Exit(0);

                        break;

                    case "HELP":

                        // display to the user the available commands if he/she typed help
                        using (var sr = new StreamReader(@"../../Intro.txt"))
                        {
                            while (!sr.EndOfStream)
                                Console.WriteLine(sr.ReadLine());
                        }
                        break;
                    default:
                        Console.WriteLine("\nSorry. That was an invalid input. Please try again. \nValid Inputs are 'Listuploadables','Upload-#','ListDownloadables','Download-#','Leave','Help'");
                        commandPrint();
                        break;
                }

            }
        }
Esempio n. 7
0
        // This method is reponsible for getting the all the file segments from the available clients and stitch all the file segments back together
        public async Task GetDownloadFile(StateObject clientState)
        {

            // Requesting the file location file the server
            var getLocationCmd = new ClientPassableObject(clientState);
            getLocationCmd.GetFilesLocation(clientState.FileNameToDownload);
            await ClientStart(getLocationCmd);
            while (getLocationCmd.DoneFlag == false) ;

            Console.WriteLine("Client: File: {0} has a length of {1}", clientState.FileNameToDownload, getLocationCmd.FileToDownloadLength);
            for (int i = 0; i < getLocationCmd.AddressAtFile2Download.Count; i++)
            {
                Console.WriteLine("Client: Address: {0}  Port: {1}", getLocationCmd.AddressAtFile2Download[i],
                    getLocationCmd.PortAtFile2Download[i]);
            }

            var DataOperator = new DataSegmentObject();
            var NoOfSegments = DataOperator.GetNoOfSegments(getLocationCmd.FileToDownloadLength, clientState.MaxChunkSize);
            List<byte[]> bytesResult = new List<byte[]>();
            List<int> ResultSegIndex = new List<int>();
            string hashResult = string.Empty;
            for (int i = 0; i < NoOfSegments; i++)
            {
                //Console.WriteLine("Client: requesting File: {0} segment: {1} from {2}  {3}", clientState.FileNameToDownload, i,
                    //getLocationCmd.AddressAtFile2Download[0], getLocationCmd.PortAtFile2Download[0]);
                var getFileCmd = new ClientPassableObject(clientState);
                getFileCmd.GetFile(getLocationCmd.AddressAtFile2Download[0], getLocationCmd.PortAtFile2Download[0], clientState.FileNameToDownload, i);
                await ClientStart(getFileCmd);
                while (getFileCmd.DoneFlag == false) ;
                //Console.WriteLine("Client: Received segment {0}", i);
                bytesResult.Add(getFileCmd.ResultFileSegment);
                ResultSegIndex.Add(getFileCmd.ResultFileSegmentNo);
                hashResult = getFileCmd.ResultFileHash;
            }
            Console.WriteLine("Received all segments of the file");

            List<string> AvailableAddresses = getLocationCmd.AddressAtFile2Download;
            List<int> AvailablePorts = getLocationCmd.PortAtFile2Download;
            int NoOfAvailableClient = AvailableAddresses.Count;


            string FileToDownload = getLocationCmd.FileToDownload;
            int SegmentDone = 0;
            int SegmentInTransit = 0;
            List<bool> BusyClient = new List<bool>();
            List<Task> task = new List<Task>();
            List<int> indexOfTasks = new List<int>();
            List<ClientPassableObject> cmd = new List<ClientPassableObject>();


            //while (SegmentDone < NoOfSegments)
            //{
            //    for (int q = 0; q < AvailableAddresses.Count; q++)
            //    {
            //        if (SegmentDone < NoOfSegments)
            //        {
            //            var getfileCmd = new ClientPassableObject(clientState);
            //            getfileCmd.GetFile(AvailableAddresses[q], AvailablePorts[q], FileToDownload, SegmentDone);
            //            Console.WriteLine("Requesting segment #{0} from {1}  ,  {2}", SegmentDone + SegmentInTransit, AvailableAddresses[q], AvailablePorts[q]);
            //            task.Add(ClientStart(getfileCmd));
            //            cmd.Add(getfileCmd);
            //            SegmentDone++;
            //            task[0].Wait();
            //        }
            //        else
            //            break;
                    
            //    }
            //    // Wait until all the tasks are complete
            //    while (true)
            //    {
            //        int counter = 0;
            //        foreach (var command in cmd)
            //        {
            //            if (command.DoneFlag)
            //                counter++;
            //        }
            //        if (counter == cmd.Count)
            //            break;
            //    }

            //    for (int k = 0; k < cmd.Count; k++)
            //    {

            //        bytesResult.Add(cmd[k].ResultFileSegment);
            //        ResultSegIndex.Add(cmd[k].ResultFileSegmentNo);
            //        hashResult = cmd[k].ResultFileHash;
            //    }
            //    task.Clear();
            //    indexOfTasks.Clear();
            //    cmd.Clear();
            //}



            //for (int i = 0; i < NoOfAvailableClient; i++)
            //    BusyClient.Add(false);

            //while (SegmentDone < NoOfSegments)
            //{
            //    if ((SegmentInTransit + SegmentDone) <= NoOfSegments)
            //    {
            //        if (BusyClient.IndexOf(false) > -1)
            //        {
            //            int j = BusyClient.IndexOf(false);

            //            var getfileCmd = new ClientPassableObject(clientState);
            //            getfileCmd.GetFile(AvailableAddresses[j], AvailablePorts[j], FileToDownload, SegmentDone + SegmentInTransit);
            //            Console.WriteLine("Requesting segment #{0} from {1}  ,  {2}", SegmentDone + SegmentInTransit, AvailableAddresses[j], AvailablePorts[j]);
            //            task.Add(ClientStart(getfileCmd));
            //            indexOfTasks.Add(j);
            //            BusyClient[j] = true;
            //            cmd.Add(getfileCmd);
            //            SegmentInTransit++;
            //        }
            //        else
            //        {
            //            for (int k = 0; k < indexOfTasks.Count; k++)
            //            {
            //                if (cmd[k].DoneFlag)
            //                {
            //                    bytesResult.Add(cmd[k].ResultFileSegment);
            //                    ResultSegIndex.Add(cmd[k].ResultFileSegmentNo);
            //                    hashResult = cmd[k].ResultFileHash;
            //                    BusyClient[indexOfTasks[k]] = false;

            //                    SegmentDone++;
            //                    SegmentInTransit--;
            //                }
            //            }
            //            for (int f = indexOfTasks.Count -1; f >= 0; f--)
            //            {
            //                if (cmd[f].DoneFlag)
            //                {
            //                    task.RemoveAt(f);
            //                    indexOfTasks.RemoveAt(f);
            //                    cmd.RemoveAt(f);
            //                }

            //            }
            //        }

            //    }

            //}

            // Reordering the info
            List<byte[]> ResultInOrder = new List<byte[]>();
            for (int k = 0; k < bytesResult.Count; k++)
            {
                int indexOfSegment = ResultSegIndex.IndexOf(k);
                ResultInOrder.Add(bytesResult[indexOfSegment]);
            }

            // Combine all the segment and compare the hashcode
            int filesize = 0;
            int accumulativeSize = 0;
            foreach (var seg in ResultInOrder)
                filesize += seg.Length;
            byte[] wholeFile = new byte[filesize];
            foreach (var seg in ResultInOrder)
            {
                System.Buffer.BlockCopy(seg, 0, wholeFile, accumulativeSize, seg.Length);
                accumulativeSize += seg.Length;
            }

            var dataparser = new DataSegmentObject();
            if (dataparser.getHashAndCompare(wholeFile, hashResult) == true)
            {
                Console.WriteLine("File: {0} is finished. You can find the file in the your desktop.");
                var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"/" + clientState.FileNameToDownload + "new";

                // Writing the whole file to the desktop 
                using (var bw = new BinaryWriter(File.Open(path, FileMode.OpenOrCreate)))
                {
                    bw.Write(wholeFile);
                }

                FileInfo f = new FileInfo(path);
                clientState.FilePathsToReg.Clear();
                clientState.FilePathsToRegLength.Clear();
                clientState.FilePathsToReg.Add(path);
                clientState.FilePathsToRegLength.Add(f.Length);
                var uploadcmd = new ClientPassableObject(clientState);
                uploadcmd.RegisterFiles();
                await ClientStart(uploadcmd);
                while (uploadcmd.DoneFlag == false) ;

                var DataParser = new DataSegmentObject();

                // splitting the files up and store it in the temp folder
                DataParser.SplitFile(path, clientState.MaxChunkSize, clientState.TempFolderPath);
                var dictObject = new ObjectForFiledict();
                dictObject.Hash = DataParser.GetHash(clientState.FilePathsToReg[0]);
                dictObject.NoOfSegments = DataParser.GetNoOfSegments(clientState.FilePathsToRegLength[0], clientState.MaxChunkSize);
                clientState.FileDict.Add(Path.GetFileName(clientState.FilePathsToReg[0]), dictObject);

            }
            else
            {
                Console.WriteLine("One of the file was corrupt. We need to retry");
            }

            commandPrint();

        }
Esempio n. 8
0
        static void Main(string[] args)
        {
            using (var sr = new StreamReader(@"../../Intro.txt"))
            {
                while (!sr.EndOfStream)
                {
                    Console.WriteLine(sr.ReadLine());
                }
            }

            Tuple <string, string> userCommand;

            /************************************************
            *
            *   This block of code is used to instantiate the server
            *
            ************************************************/
            //var tcpServer = new TcpTorrent();
            //var serverState = new StateObject();
            //serverState.ClientType = false;
            //var serverTask = tcpServer.StartListener(serverState);

            //tcpServer.StartListener(serverState).Wait();

            /************************************************
            *
            *   This block of code is used to instantiate the client server
            *
            ************************************************/
            StateObject clientState  = new StateObject();
            var         clientServer = new TcpTorrent();

            clientState.Address = "127.0.0.1";
            //clientState.Address = clientServer.GetLocalIPAddress();
            clientState.Port = clientServer.GetOpenPort();
            Console.WriteLine("Creating Client's server on Address: {0} , and Port: {1}", clientState.Address, clientState.Port);
            var task = clientServer.StartListener(clientState);

            // Creating a temp location to store all the temporary files
            var random = new Random();

            clientState.TempFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"/Temp" + random.Next(1, 10);
            if (!Directory.Exists(clientState.TempFolderPath))
            {
                Console.WriteLine("Client: Creating directory at {0}", clientState.TempFolderPath);
                Directory.CreateDirectory(clientState.TempFolderPath);
            }
            else
            {
                clientState.TempFolderPath += random.Next(1, 10);
                Console.WriteLine("Client: Creating directory at {0}", clientState.TempFolderPath);
                Directory.CreateDirectory(clientState.TempFolderPath);
            }

            commandPrint();


            while (true)
            {
                Thread.Sleep(200);
                userCommand = getCommand();

                // Switching through all the user's input
                switch (userCommand.Item1)
                {
                case "LISTUPLOADABLES":
                    // Clearing the previous file paths since we are repopulating it
                    clientState.UploadableFilePath.Clear();
                    clientState.UploadableFileSize.Clear();

                    // Displaying all the files that are in the desktop folder
                    string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                    int    i    = 1;
                    Console.WriteLine("\nThe following files are available for download");
                    foreach (var file in Directory.GetFiles(path))
                    {
                        // Only present the file if it hasn't already been added
                        if (!clientState.FileDict.ContainsKey(Path.GetFileName(file)))
                        {
                            FileInfo f = new FileInfo(file);
                            Console.WriteLine("{0}) {1}", i, Path.GetFileName(file));
                            clientState.UploadableFilePath.Add(file);

                            clientState.UploadableFileSize.Add(f.Length);
                        }
                        i++;
                    }
                    commandPrint();
                    break;

                case "UPLOAD":


                    Tuple <bool, string> validCheck = IsValidInput(userCommand.Item2, clientState.UploadableFilePath.Count);

                    // If any of the value in the previous loop was invalid, we need to break out of this case.
                    if (validCheck.Item1 == false)
                    {
                        Console.WriteLine(validCheck.Item2);
                        commandPrint();
                        break;
                    }

                    // Now what we know that the user's inputs are valid, we need to store the path of the files that the user wants to upload

                    // Clearing the previous FilestoREg list because we have a new list.
                    clientState.FilePathsToReg.Clear();
                    clientState.FilePathsToRegLength.Clear();
                    foreach (string item in userCommand.Item2.Split(','))
                    {
                        clientState.FilePathsToReg.Add(clientState.UploadableFilePath[Convert.ToInt32(item) - 1]);
                        clientState.FilePathsToRegLength.Add(clientState.UploadableFileSize[Convert.ToInt32(item) - 1]);
                    }

                    // creating a new tcp client with the command to register the files that the user had selected
                    var uploadcmd = new ClientPassableObject(clientState);
                    uploadcmd.RegisterFiles();
                    var uploadclient = new TcpTorrent();
                    var clienttask   = uploadclient.ClientStart(uploadcmd);

                    while (uploadcmd.DoneFlag == false)
                    {
                        ;
                    }

                    // Now that we recieved upload on which file can be uploaded, we need to split the files up into segments and store it in the temp folder
                    for (int j = 0; j < uploadcmd.FilesRegSuccessCount.Count; j++)
                    {
                        if (uploadcmd.FilesRegSuccessCount[j] == true)
                        {
                            // Only do something if we don't already have the file in storage.
                            if (!clientState.FileDict.ContainsKey(Path.GetFileName(clientState.FilePathsToReg[j])))
                            {
                                var DataParser = new DataSegmentObject();

                                // splitting the files up and store it in the temp folder
                                DataParser.SplitFile(clientState.FilePathsToReg[j], clientState.MaxChunkSize, clientState.TempFolderPath);
                                var dictObject = new ObjectForFiledict();
                                dictObject.Hash         = DataParser.GetHash(clientState.FilePathsToReg[j]);
                                dictObject.NoOfSegments = DataParser.GetNoOfSegments(clientState.FilePathsToRegLength[j], clientState.MaxChunkSize);

                                Console.WriteLine("Client: splitting file: {0} of length {1} to {2} segments",
                                                  clientState.FilePathsToReg[j], clientState.FilePathsToRegLength[j], dictObject.NoOfSegments);


                                clientState.FileDict.Add(Path.GetFileName(clientState.FilePathsToReg[j]), dictObject);
                            }
                            else
                            {
                                Console.WriteLine("Client: The file already exist in the dictionary. Do not add");
                            }
                        }
                    }

                    commandPrint();


                    break;

                case "LISTDOWNLOADABLES":

                    // Creating a new tcp client that will get all the downloadable files
                    var printcmd = new ClientPassableObject(clientState);
                    printcmd.PrintDownloadable();
                    var printListclient = new TcpTorrent();
                    var printTask       = printListclient.ClientStart(printcmd);

                    while (printcmd.DoneFlag == false)
                    {
                        ;
                    }

                    clientState.DownloadableFileName = printcmd.DownloadableFiles;
                    clientState.DownloadableFileSize = printcmd.DownloadableFilesLength;
                    commandPrint();

                    break;


                case "DOWNLOAD":
                    Tuple <bool, string> downloadValidCheck = IsValidInput(userCommand.Item2, clientState.DownloadableFileName.Count);

                    // If any of the value in the previous loop was invalid, we need to break out of this case.
                    if (downloadValidCheck.Item1 == false)
                    {
                        Console.WriteLine(downloadValidCheck.Item2);
                        commandPrint();
                        break;
                    }
                    // We are only going to allow one file to be download at a time
                    if (userCommand.Item2.Split(',').Length > 1)
                    {
                        Console.WriteLine("/nYou can only select one download file at a time");
                        break;
                    }

                    // Clearing the previous FilestoREg list because we have a new list.
                    clientState.FileNameToDownload       = string.Empty;
                    clientState.FileNameToDownloadLength = 0;

                    clientState.FileNameToDownload       = clientState.DownloadableFileName[Convert.ToInt32(userCommand.Item2) - 1];
                    clientState.FileNameToDownloadLength = clientState.DownloadableFileSize[Convert.ToInt32(userCommand.Item2) - 1];

                    // Creating a new TCP client that will download the file from the other client
                    var downloadClient = new TcpTorrent();
                    var downloadTask   = downloadClient.GetDownloadFile(clientState);
                    Thread.Sleep(2000);
                    break;

                case "LEAVE":

                    // createing a new tcp client that will request to leave
                    var leaveCmd = new ClientPassableObject(clientState);
                    leaveCmd.LeaveRequest();
                    var leaveClient = new TcpTorrent();
                    //Console.WriteLine("Creating leave task");
                    var leaveTask = leaveClient.ClientStart(leaveCmd);
                    while (leaveCmd.DoneFlag == false)
                    {
                        ;
                    }

                    if (Directory.Exists(clientState.TempFolderPath))
                    {
                        Console.WriteLine("Client: deleting directory at {0}", clientState.TempFolderPath);
                        Directory.Delete(clientState.TempFolderPath, true);
                    }
                    else
                    {
                        Console.WriteLine("Client: Directory to delete doesn't exist");
                    }

                    Console.ReadKey();
                    Environment.Exit(0);

                    break;


                case "HELP":

                    // display to the user the available commands if he/she typed help
                    using (var sr = new StreamReader(@"../../Intro.txt"))
                    {
                        while (!sr.EndOfStream)
                        {
                            Console.WriteLine(sr.ReadLine());
                        }
                    }
                    break;

                default:
                    Console.WriteLine("\nSorry. That was an invalid input. Please try again. \nValid Inputs are 'Listuploadables','Upload-#','ListDownloadables','Download-#','Leave','Help'");
                    commandPrint();
                    break;
                }
            }
        }