protected override void Run() { Log.Debug("Started sender"); var persistence = new PersistenceManager(); while (true) { if (Token.IsCancellationRequested) { Log.Debug("Received request to stop"); return; } if (IncomingMessages.Count == 0) { continue; } using (var file = File.Open(Path.Combine(FileInfo.LocalPath, FileInfo.FileName), FileMode.Open)) using (var stream = new BinaryReader(file)) { while (IncomingMessages.Count > 0) { Message mesg; if (IncomingMessages.TryDequeue(out mesg)) { if (mesg.MessageId == MessageType.CHUNK_REQUEST) { var chunkReq = (ChunkRequest)mesg; stream.BaseStream.Seek(chunkReq.Size * chunkReq.Index, SeekOrigin.Begin); var bytes = stream.ReadBytes(chunkReq.Size); var provider = new RSACryptoServiceProvider(); provider.ImportCspBlob(persistence.ReadContent().KeyInfo); Log.DebugFormat("Building ChunkReply message for index {0}", chunkReq.Index); var outMessage = new ChunkReply(Guid.NewGuid(), chunkReq.ConversationId, chunkReq.MessageCount + 1, bytes, chunkReq.Index, MessageVerifier.CreateSignature(bytes, provider.ExportParameters(true))); RaiseSendMessageEvent(outMessage); } else if (mesg.MessageId == MessageType.ACKNOWLEDGE) { Log.Info("Client acknowledged that it has received all the data"); CancelSource.Cancel(); RaiseEndConversationEvent(); } } } } } }
protected override void Run() { Log.Debug("Started receiver"); // Only request all packets five times while (true) { if (Token.IsCancellationRequested) { Log.Debug("Received request to stop"); break; } foreach (var data in NeededData) { var chunkReq = new ChunkRequest(Guid.NewGuid(), ConversationId, MessageCount, data, FileInfo.ContentHash, ChunkSize); RaiseSendMessageEvent(chunkReq); MessageCount++; } Thread.Sleep(250); while (IncomingMessages.Count > 0) { Message mesg; if (IncomingMessages.TryDequeue(out mesg)) { if (mesg.MessageId == MessageType.CHUNK_REPLY) { var chunkReply = (ChunkReply)mesg; if (NeededData.Contains(chunkReply.Index)) { var provider = new RSACryptoServiceProvider(); provider.ImportCspBlob(FileInfo.PublicKeyInfo); if (MessageVerifier.CheckSignature(chunkReply.ChunkData, chunkReply.Signature, provider.ExportParameters(false))) { DataStore[chunkReply.Index] = chunkReply.ChunkData; NeededData.Remove(chunkReply.Index); ReceivedData.Add(chunkReply.Index); if (NeededData.Count == 0) { Log.Info(string.Format("Conversation complete; Downloaded {0} packets", DataStore.Count)); var ack = new Acknowledge(Guid.NewGuid(), ConversationId, mesg.MessageCount + 1, "Download complete"); CancelSource.Cancel(); RaiseSendMessageEvent(ack); break; } } else { Log.Warn("Message signature is NOT verfied"); } } } } } Thread.Sleep(250); } RaiseEndConversationEvent(); }