Beispiel #1
0
 public UserClient(Client networkClient)
 {
     NetworkClient            = networkClient;
     LastActivity             = DateTime.UtcNow;
     Buffer                   = new MemoryStream(1024);
     CurrentTransmitDirection = FileTransmitDirection.None;
 }
Beispiel #2
0
        protected override void OnData(byte[] buffer, int offset, int length, CancellationToken cancellationToken)
        {
            //Logger.Log(LogType.Debug, "Received {0} bytes", length);
            if (length != 0)
            {
                DataLogger.Log(buffer, offset, length);
            }

            if (_currentFileTransmission != null &&
                _currentTransmitDirection == FileTransmitDirection.Receive)
            {
                if (_buffer.Length > 0)
                {
                    var len = _buffer.Length;
                    _buffer.Position = 0;
                    _buffer.SetLength(0);
                    OnData(_buffer.GetBuffer(), 0, (int)len, cancellationToken);
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }
                }

                if (length == 0)
                {
                    return;
                }

                //Logger.Log(LogType.Debug, "Remaining: {0}", _currentFileTransmission.Remaining);

                // we're currently receiving a file
                int toWrite = (int)Math.Min(length, _currentFileTransmission.Remaining);
                _currentFileTransmission.Write(buffer, offset, toWrite);

                //Logger.Log(LogType.Debug, "Wrote {0} bytes - Remaining {1}", toWrite, userClient.FileTransmit.Remaining);

                if (_currentFileTransmission.Remaining == 0)
                {
                    _currentFileTransmission.EndReceive();

                    Logger.Log(LogType.Normal, "File complete: {0}", _currentFileTransmission.RemotePath);

                    if (_currentFileTransmission.IsFileCorrupted)
                    {
                        Logger.Log(LogType.Error, "ERR FILE CORRUPTED => {0}", _currentFileTransmission.RemotePath);
                    }

                    _currentFileTransmission.Dispose();
                    _currentFileTransmission  = null;
                    _currentTransmitDirection = FileTransmitDirection.None;

                    //CreatePacket(PacketHeader.TransmitComplete).Send(); // notify transmit completed

                    if ((length - toWrite) > 0)
                    {
                        var newBuffer = new byte[length - toWrite];
                        Buffer.BlockCopy(buffer, offset + toWrite, newBuffer, 0, length - toWrite);
                        OnData(newBuffer, 0, newBuffer.Length, cancellationToken); // read the remaining data
                    }
                }

                return;
            }

            _buffer.Position = _buffer.Length;
            _buffer.Write(buffer, offset, length);

            ReadPacketResult result;

            do
            {
                _buffer.Position = 0;

                int   requestId;
                short header;
                int   dataSize;

                switch (result = Utilities.ReadHeader(_buffer, out requestId, out header, out dataSize))
                {
                case ReadPacketResult.InvalidData:
                case ReadPacketResult.DataSizeInvalid:
                case ReadPacketResult.InvalidHeader:
                case ReadPacketResult.UnexpectedHeaderAtThisPoint:
                    Logger.Log(
                        LogType.Warning,
                        "ReadHeader: {0}",
                        Enum.GetName(typeof(ReadPacketResult), result));
                    Utilities.DumpData(_buffer.GetBuffer(), (int)_buffer.Length);
                    //Close();
                    return;

                case ReadPacketResult.NeedMoreData:
                    return;     // exit out of OnClientData and wait for more data...
                }

                // call packet methods

                MethodInfo methodInfo;
                if (!_packetMethods.TryGetValue((PacketHeader)header, out methodInfo))
                {
                    Logger.Log(
                        LogType.Warning,
                        "Unknown packet header: 0x{0}",
                        header.ToString("x4"));
                    Close();
                    return;
                }

                try
                {
                    methodInfo.Invoke(this, new object[] { requestId });
                }
                catch (TargetInvocationException ex)
                {
                    if (ex.InnerException is DataValidationException)
                    {
                        Close(ex.Message);
                    }
                    else if (ex.InnerException is FileTransmitBeginException)
                    {
                        _buffer.Delete(NetworkStandards.HeaderSize + dataSize);
                        OnData(new byte[] { }, 0, 0, cancellationToken);
                        return;
                    }
                }

                if (!IsConnected)
                {
                    return;
                }

                _buffer.Delete(NetworkStandards.HeaderSize + dataSize);

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                if (_currentTransmitDirection == FileTransmitDirection.Receive)
                {
                    OnData(new byte[] { }, 0, 0, cancellationToken);
                    return;
                }

                if (_buffer.Length == 0)
                {
                    break;
                }
            }while (result == ReadPacketResult.Succeeded);
        }
Beispiel #3
0
        public void TransferFile(string localFilename, string remoteFilename, FileTransmitDirection direction, TimeSpan timeout)
        {
            if (direction == FileTransmitDirection.Send)
            {
                var fi        = new FileInfo(localFilename);
                var succeeded = false;

                var crc = new Crc32().ComputeFile(fi.FullName);

                using (var request = CreateRequest())
                {
                    CreatePacket(request.Id, PacketHeader.TransferFileRequest)
                    .Write((byte)1)     // send
                    .Write(remoteFilename)
                    .Write(fi.Length)
                    .Write(fi.LastWriteTimeUtc.Ticks)
                    .Write(crc)
                    .Send();

                    if (!WaitForRequest(request, timeout))
                    {
                        throw new RequestTimeoutException();
                    }

                    succeeded = (bool)request.Data;
                }

                if (!succeeded)
                {
                    throw new InvalidOperationException("Failed to request to transfer file...");
                }

                using (var stream = System.IO.File.Open(localFilename, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var pos    = 0L;
                    var buffer = new byte[65536];

                    while (pos < fi.Length)
                    {
                        var read = stream.Read(buffer, 0, (int)Math.Min(buffer.Length, fi.Length - pos));
                        pos += read;

                        var sendPos = 0;
                        while (sendPos < read)
                        {
                            var sent = Send(buffer, sendPos, read - sendPos);
                            if (sent <= 0)
                            {
                                throw new Exception("TransferFile Send error. Return value: " + sent);
                            }

                            sendPos += sent;
                        }
                    }
                }
            }
            else // receive
            {
                FileRequestResult result;

                using (var request = CreateRequest())
                {
                    CreatePacket(request.Id, PacketHeader.TransferFileRequest)
                    .Write((byte)0)     // receive
                    .Write(remoteFilename)
                    .Send();

                    if (!WaitForRequest(request, timeout))
                    {
                        throw new RequestTimeoutException();
                    }

                    result = (FileRequestResult)request.Data;
                }

                if (!result.Succeeded)
                {
                    throw new InvalidOperationException("Failed to request to receive file...");
                }

                // receive data...
                _currentTransmitDirection = FileTransmitDirection.Receive;
                _currentFileTransmission  = FileTransmission.BeginReceive(
                    localFilename,
                    remoteFilename,
                    result.LastWriteTimeUtc,
                    result.Size,
                    Path.GetTempFileName(),
                    result.Crc);
            }
        }
Beispiel #4
0
        public override void Process(CancellationToken cancellationToken)
        {
            base.Process(cancellationToken);

            if (!IsConnected)
            {
                return;
            }

            int tick = Environment.TickCount;

            if (_isAuthorized)
            {
                if (tick >= _nextSendPing &&
                    (_currentFileTransmission == null ||
                     !_currentFileTransmission.IsTransmitting))
                {
                    _nextSendPing = tick + 10000;
                    CreatePacket(0, PacketHeader.Ping).Send();
                }

                // check queue
                if (_currentFileTransmission != null &&
                    _currentTransmitDirection == FileTransmitDirection.Send)
                {
                    if (_currentFileTransmission.IsTransmitting)
                    {
                        // send chunk...
                        int toSend = (int)Math.Min(_currentFileTransmission.Remaining, _fileTransmitBuffer.Length);

                        int numberOfBytesRead = 0;
                        while (numberOfBytesRead < toSend)
                        {
                            numberOfBytesRead += _currentFileTransmission.Read(_fileTransmitBuffer, 0, toSend - numberOfBytesRead);
                        }

                        int numberOfBytesSent = 0;
                        while (numberOfBytesSent < toSend)
                        {
                            numberOfBytesSent += Send(_fileTransmitBuffer, 0, toSend - numberOfBytesSent);
                        }

                        if (_currentFileTransmission.Remaining == 0)
                        {
                            // file upload completed
                            Logger.Log(LogType.Normal, "Transmit completed.");

                            _currentFileTransmission.EndTransmit();
                            _currentFileTransmission.Dispose();
                            _currentFileTransmission  = null;
                            _currentTransmitDirection = FileTransmitDirection.None;
                        }
                    }
                }
                else if (_fileTransmissionQueue.Count > 0)
                {
                    _currentFileTransmission  = _fileTransmissionQueue.Dequeue();
                    _currentTransmitDirection = FileTransmitDirection.Send;

                    /*Logger.Log(
                     *  LogType.Debug,
                     *  "Request transmit {0}",
                     *  _currentFileTransmission.LocalPath);*/

                    CreatePacket(0, PacketHeader.Store)
                    .Write(_currentFileTransmission.RemotePath)
                    .Write(_currentFileTransmission.FileSize)
                    .Write(_currentFileTransmission.FileDateUtc.Ticks)
                    .Write((int)_currentFileTransmission.RemoteChecksum)
                    .Send();
                }
            }
        }