/// <summary> /// Read a file chunk request` /// </summary> /// <param name="from">Origin</param> /// <param name="filename">Filename to read from</param> /// <param name="offset">Offset in the file</param> /// <param name="maxLength">Maximum chunk length</param> /// <returns>Number of bytes read</returns> public static int ReadFileChunkRequest(ReadOnlySpan <byte> from, out string filename, out uint offset, out uint maxLength) { FileChunkHeader header = MemoryMarshal.Cast <byte, FileChunkHeader>(from)[0]; int bytesRead = Marshal.SizeOf(header); // Read header offset = header.Offset; maxLength = header.MaxLength; // Read filename ReadOnlySpan <byte> unicodeFilename = from.Slice(bytesRead, (int)header.FilenameLength); filename = Encoding.UTF8.GetString(unicodeFilename); bytesRead += (int)header.FilenameLength; return(AddPadding(bytesRead)); }
private void HandleFileSend(FileRequestMessage requestMessage) { if (!requestMessage.RequestedFile.Exists) { ClientProtocol.SendFileTransferFailure(requestMessage.RequestedFile); return; } long chunkIndex = requestMessage.Header.ChunkIndex; using (FileStream file = requestMessage.RequestedFile.OpenForRead()) { FileChunkHeader header = new FileChunkHeader(); header.ChunkCount = (int)Math.Ceiling((double)file.Length / Settings.FileChunkSize); header.ChunkIndex = chunkIndex; header.Id = requestMessage.Header.Id; header.Hash = requestMessage.RequestedFile.Hash; using (FileChunkMessage message = new FileChunkMessage(header)) { long offset = chunkIndex * Settings.FileChunkSize; int length = (int) (offset + Settings.FileChunkSize > file.Length ? file.Length - offset : Settings.FileChunkSize); byte[] chunk = new byte[length]; file.Seek(offset, SeekOrigin.Begin); file.Read(chunk, 0, chunk.Length); try { ClientProtocol.AddDataToMessage(message, chunk); ClientProtocol.SendMessage(message); } catch (Exception e) { throw e; } } } }