private void HandleFileDownload(NetworkStream networkStream) { // Get client download file header var clientHeader = GetClientDownloadFileHeader(networkStream); // Check file availability var query = FileDB.FileEntries.Where(f => f.Name == clientHeader.Filename); if (query.Count() < 1 || query.First().ToBeDeleted) { var negativeResponseBytes = BitConverter.GetBytes((int)ResponeType.Failure); networkStream.Write(negativeResponseBytes, 0, negativeResponseBytes.Length); return; } else { ++query.First().CurrentUses; var positiveResponseBytes = BitConverter.GetBytes((int)ResponeType.Success); networkStream.Write(positiveResponseBytes, 0, positiveResponseBytes.Length); } int fileSize = FileDB.GetFileLength(clientHeader.Filename); int numBlocks = fileSize / BlockSize; int lastBlockSize = fileSize % BlockSize; var serverHeader = new ServerDownloadFileHeader() { FileSize = fileSize, NumBlocks = numBlocks, LastBlockSize = lastBlockSize }; var serverHeaderBytes = SerializationMethods.Serialize(serverHeader); var serverHeaderLengthBytes = BitConverter.GetBytes(serverHeaderBytes.Length); networkStream.Write(serverHeaderLengthBytes, 0, serverHeaderLengthBytes.Length); networkStream.Write(serverHeaderBytes, 0, serverHeaderBytes.Length); var downloadSession = new FileDownloadSession(FileDB, clientHeader.Filename); for (int i = 0; i < numBlocks; i++) { var fileData = FileDB.GetFileDataAtV2(downloadSession, i * BlockSize, (i + 1) * BlockSize - 1); networkStream.Write(fileData, 0, fileData.Length); } if (lastBlockSize > 0) { var file_data = FileDB.GetFileDataAtV2(downloadSession, numBlocks * BlockSize, fileSize - 1); networkStream.Write(file_data, 0, file_data.Length); } downloadSession.TerminateSession(); --query.First().CurrentUses; }