예제 #1
0
        /// <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;
                    }
                }
            }
        }