Beispiel #1
0
        /// <summary>
        /// Handles the deletion of a chunk of the file
        /// </summary>
        /// <param name="currentFileChunk">The P2PChunk to be deleted</param>
        /// <param name="currentFile">The P2PFile to wich the chunk belongs</param>
        /// <returns></returns>
        public bool ChunkDeleter(P2PChunk currentFileChunk, P2PFile currentFile){
            Listener listener = new Listener(this._port);

            int lastIndex = currentFileChunk.peers.Count - 1;
            //Sends a delete message to every peer with the chunk
            for (int i = lastIndex; i >= 0; i--) {
                if (_peers.TryGetValue(currentFileChunk.peers[i], out Peer currentReceiver)) {
                    if (!currentReceiver.IsOnline()){
                        return false;
                    }
                    var deletionMessage = new FileDeletionMessage(currentReceiver) {
                        type = TypeCode.REQUEST,
                        statusCode = StatusCode.OK,
                        port = _port,
                        fileHash = currentFileChunk.hash,
                        fullFileHash = currentFile.hash
                    };

                    //Sends the message and waits for a response,
                    //which will then overwrite the original sent message
                    if (listener.SendAndAwaitResponse(ref deletionMessage, 2000)) {
                        if (deletionMessage.type.Equals(TypeCode.RESPONSE)) {
                            currentFileChunk.RemovePeer(deletionMessage.fromUuid);
                            if (currentFileChunk.peers.Count == 0) {
                                currentFile.RemoveChunk(currentFileChunk.hash);
                            }
                            if (deletionMessage.statusCode.Equals(StatusCode.FILE_NOT_FOUND)) {
                                DiskHelper.ConsoleWrite("File not found at peer");
                            }
                        }
                    }
                }
            }
            return true;
        }
Beispiel #2
0
        /// <summary>
        /// Pushes the inputted chunk to the network, sending it the required amount of peers.
        /// </summary>
        /// <param name="chunk">The chunk to push to the network</param>
        /// <param name="chunkPath">String path to the chunks</param>
        /// <param name="numberOfRecevingPeers">The number of peers to send the file to,
        /// this will be the amount of receivers, unless the network is smaller than the given input.</param>
        /// <param name="receiverOffset">The offset for whom to send the files to, this determines the spacing of the chunks on the peerlist.</param>
        /// <returns>Boolean of whether the push was a success.</returns>
        public bool Push(P2PChunk chunk, string chunkPath, int numberOfRecevingPeers = 10, int receiverOffset = 0)
        {
            this._port = _ports.GetAvailablePort();
            List <Peer> peers      = this.GetPeers();
            FileInfo    fileInfo   = new FileInfo(chunkPath);
            Listener    listener   = new Listener(this._port);
            bool        sendToAll  = true;
            int         listLength = peers.Count;
            int         peerCount;
            int         numberOfReceivers = Math.Min(numberOfRecevingPeers, listLength);

            for (peerCount = 0; peerCount < numberOfReceivers; peerCount++)
            {
                Peer currentPeer = peers[(peerCount + receiverOffset) % listLength];
                var  upload      = new UploadMessage(currentPeer)
                {
                    filesize     = fileInfo.Length,
                    fullFilename = chunk.originalHash,
                    chunkHash    = chunk.hash,
                    path         = chunkPath,
                    port         = this._port
                };

                if (listener.SendAndAwaitResponse(ref upload, 2000))
                {
                    if (upload.statusCode == StatusCode.ACCEPTED)
                    {
                        ChunkSender sender = new ChunkSender(currentPeer.StringIp, upload.port);

                        if (sender.Send(chunkPath))
                        {
                            DiskHelper.ConsoleWrite($"The chunk {chunk.hash} was sent to {currentPeer.GetUuid()}");
                            chunk.AddPeer(currentPeer.GetUuid());
                        }
                        else
                        {
                            sendToAll = false;
                        }
                        _ports.Release(upload.port);
                    }
                }
            }

            _ports.Release(this._port);
            return(sendToAll);
        }
Beispiel #3
0
        /// <summary>
        /// Fetching function, this fetches the given chunk from the network, returns true if the chunk is fetched.
        /// </summary>
        /// <param name="chunk">The chunk wanted to download.</param>
        /// <param name="fullFileName">The name of the full file.</param>
        /// <returns>Rather the chunk has been fetched.</returns>
        public bool Fetch(P2PChunk chunk, string fullFileName)
        {
            _port       = _ports.GetAvailablePort();
            _hash       = chunk.hash;
            _peersToAsk = chunk.peers;
            Listener listener = new Listener(this._port);

            foreach (var peer in _peersToAsk)
            {
                if (!_peers.TryGetValue(peer, out Peer currentPeer))
                {
                    break;
                }

                if (currentPeer.IsOnline())
                {
                    var download = new DownloadMessage(currentPeer)
                    {
                        port         = this._port,
                        fullFileName = chunk.originalHash,
                        filehash     = _hash
                    };

                    // Sends the download message and waits for a
                    // "response" download message to be received.
                    // Then changed 'download' to this message and
                    // returns true. If a response is not received
                    // within time, it returns false.
                    if (listener.SendAndAwaitResponse(ref download, 3000))
                    {
                        // If the download is accepted, a receiver is
                        // started and the port of the receiver is
                        // sent to the peer.
                        if (download.statusCode == StatusCode.ACCEPTED)
                        {
                            int receiverPort = _ports.GetAvailablePort();
                            download.CreateReply();
                            download.type       = Messages.TypeCode.REQUEST;
                            download.statusCode = StatusCode.ACCEPTED;
                            download.port       = receiverPort;

                            if (!Directory.Exists(_path + fullFileName + @"\"))
                            {
                                Directory.CreateDirectory(_path + fullFileName + @"\");
                            }

                            download.Send();

                            if (!currentPeer.IsOnline())
                            {
                                DiskHelper.ConsoleWrite("The peer requested went offline.");
                                continue;
                            }
                            DiskHelper.ConsoleWrite("FileReceiver opened");
                            if (!Downloader(fullFileName, receiverPort))
                            {
                                return(false);
                            }

                            _ports.Release(download.port);
                            break;
                        }
                        else if (download.statusCode == StatusCode.FILE_NOT_FOUND)
                        {
                            Console.WriteLine("File not found at peer.");
                            chunk.peers.Remove(download.fromUuid);
                        }
                    }
                }
            }

            if (File.Exists(_path + fullFileName + @"\" + _hash))
            {
                if (CheckDownloadHash(_path + fullFileName + @"\" + _hash, _hash))
                {
                    DiskHelper.ConsoleWrite(@"Chunk done downloading");
                    return(true);
                }
            }

            return(false);
        }