/// <summary> /// Method used to request the download of a chunk from the network. When it is invoked from /// a remote peer it gets the chunk from the file and calls back the ReturnChunk method /// of the requestor. /// </summary> /// <param name="chkrq">Message used to pass information about the Chunk requested</param> public void GetChunk(ChunkRequest chkrq) { log.Info("Received request to send chunk!"); servingBuffer++; TrackModel track = new TrackModel(); RepositoryResponse resp = trackRepository.GetByKey<TrackModel.Track>(chkrq.RID, track); log.Debug("Searching track " + track + " in repository"); if (resp >= 0) { log.Debug("Track found! Extracting chunk."); byte[] data; using (FileStream fs = new FileStream(track.Filepath, FileMode.Open, FileAccess.Read, FileShare.Read)) { int limit = (System.Convert.ToInt32(fs.Length) > (chunkLength * 1024 * (chkrq.CID + 1))) ? chunkLength * 1024 * (chkrq.CID + 1) : (System.Convert.ToInt32(fs.Length)); int begin = chkrq.CID * chunkLength * 1024; data = new byte[limit - begin]; Console.WriteLine("Reading chunk " + chkrq.CID + " (" + (chkrq.CID * chunkLength * 1024) + " => " + limit + ")"); fs.Seek(begin, SeekOrigin.Begin); fs.Read(data, 0, (limit - begin)); fs.Close(); } ChunkResponse chkrs = new ChunkResponse(servingBuffer, chkrq.RID, chkrq.CID, data, myAddress); if (chkrq.SenderAddress != myAddress) { ITransportProtocol svc = ChannelFactory<ITransportProtocol>.CreateChannel( new NetUdpBinding(), new EndpointAddress(chkrq.SenderAddress) ); svc.ReturnChunk(chkrs); } else { this.ReturnChunk(chkrs); } log.Debug("Chunk sent to " + chkrq.SenderAddress); } servingBuffer--; }
/// <summary> /// Method used to require the chunk to the remote peer. /// </summary> /// <param name="chkrq">The message containing informations about the request</param> /// <param name="address">The address of the peer to whom require the chunk</param> private void getRemoteChunk(ChunkRequest chkrq, string address) { if (address != this.myAddress.ToString()) { log.Debug("Requesting for chunk " + chkrq.CID + " to remote peer: " + address); peerQueue[address].GetChunk(chkrq); } else { this.GetChunk(chkrq); } }
/// <summary> /// Method used to require a chunk to the peer represented by the inner channel. /// </summary> /// <param name="chkrq">ChunkRequest object containing informations about the resource.</param> /// <seealso cref="TransportService.Messages.ChunkRequest"/> public void GetChunk(ChunkRequest chkrq) { this.State = PeerState.BUSY; this.TimedPeerBlock(3000); this.channel.GetChunk(chkrq); }