Пример #1
0
        internal void EndAcceptControlConnection(IAsyncResult ar)
        {
            try {
                string _filePath     = (string)ar.AsyncState;
                Socket _clientSocket = controlSocket.EndAccept(ar);
                NetworkCommunicationManagers.Disconnect(controlSocket);
                controlSocket = _clientSocket;
                byte[] _buffer = packFileMetadata(_filePath);

                NetworkCommunicationManagers.SendIntOverSocket(dataSocket, _buffer.Length);
                NetworkCommunicationManagers.SendByteArrayOverSocket(dataSocket, _buffer);

                fileTransferContainer.FileTransferClassInstance = this;
                managedSendFileOverSockets(_filePath);
            }
            catch (Exception) {
                NetworkCommunicationManagers.Disconnect(controlSocket);
                NetworkCommunicationManagers.Disconnect(dataSocket);
                lock (RunningTransfers) {
                    if (fileTransferContainer.status != FileTransferStatus.Cancelled)
                    {
                        fileTransferContainer.status = FileTransferStatus.Error;
                    }
                }
                return;
            }
        }
Пример #2
0
        internal void managedSendFileOverSockets(string filePath)
        {
            fileTransferContainer.filePath = filePath;

            short       _count   = 0;
            const short _INITIAL = 5000;

            Thread _thread = new Thread(() => monitorControlChannel());

            _thread.Name         = "Control Socket monitor for " + dataSocket.RemoteEndPoint.ToString();
            _thread.IsBackground = true;
            _thread.Start();

            using (FileStream _fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
                byte[] _fileBuffer = new byte[FILE_BUFFER_SIZE];

                long _size = _fs.Length;

                try {
                    long _index = 0;

                    //Send the initial chunk of data
                    while (dataSocket.Connected && controlSocket.Connected && _index < _size)
                    {
                        if (fileTransferContainer.status == FileTransferStatus.Paused)
                        {
                            resetEvent.WaitOne();
                        }

                        _fs.Position = _index;
                        int _read = _fs.Read(_fileBuffer, 0, _fileBuffer.Length);

                        try {
                            NetworkCommunicationManagers.SendIntOverSocket(dataSocket, _read);

                            if (_read != _fileBuffer.Length)
                            {
                                byte[] _temp = new byte[_read];
                                Buffer.BlockCopy(_fileBuffer, 0, _temp, 0, _read);
                                NetworkCommunicationManagers.SendByteArrayOverSocket(dataSocket, _temp);
                            }
                            else
                            {
                                NetworkCommunicationManagers.SendByteArrayOverSocket(dataSocket, _fileBuffer);
                            }
                        }
                        catch (SocketException) {
                            continue;
                        }

                        _index += _read;
                        _count++;
                        if (_count % 200 == 0)
                        {
                            lock (RunningTransfers) {
                                if (Math.Round(((((double)_index / _size) * 100) - fileTransferContainer.progress), 1) >= 0.1)
                                {
                                    fileTransferContainer.progress = (float)Math.Round(((double)_index / _size) * 100, 1);
                                }
                            }
                        }
                        if (_count == _INITIAL)
                        {
                            _count = 0;
                            break;
                        }
                    }

                    //Send the remaining data
                    while (dataSocket.Connected && controlSocket.Connected && _index < _size)
                    {
                        _fs.Position = _index;
                        int _read = _fs.Read(_fileBuffer, 0, _fileBuffer.Length);

                        try {
                            NetworkCommunicationManagers.SendIntOverSocket(dataSocket, _read);
                            if (_read != _fileBuffer.Length)
                            {
                                byte[] _temp = new byte[_read];
                                Buffer.BlockCopy(_fileBuffer, 0, _temp, 0, _read);
                                NetworkCommunicationManagers.SendByteArrayOverSocket(dataSocket, _temp);
                            }
                            else
                            {
                                NetworkCommunicationManagers.SendByteArrayOverSocket(dataSocket, _fileBuffer);
                            }
                        }
                        catch (SocketException) {
                            continue;
                        }

                        _index += _read;
                        _count++;
                        if (_count % 200 == 0)
                        {
                            lock (RunningTransfers){
                                if (Math.Round(((((double)_index / _size) * 100) - fileTransferContainer.progress), 1) >= 0.1)
                                {
                                    fileTransferContainer.progress = (float)Math.Round((((double)_index / _size) * 100), 1);
                                }
                            }
                            bool _wait = true;
                            while (true)
                            {
                                lock (syncObject) {
                                    if (acknowledgedTransfers > 0)
                                    {
                                        acknowledgedTransfers--;
                                        _wait = false;
                                        break;
                                    }
                                }
                                if (_wait)
                                {
                                    Thread.Sleep(100);
                                }
                            }
                        }
                    }
                    if (_index == _size)
                    {
                        lock (RunningTransfers) {
                            fileTransferContainer.progress = 100;
                            fileTransferContainer.status   = FileTransferStatus.Finished;
                        }
                    }
                    else
                    {
                        lock (RunningTransfers) {
                            if (fileTransferContainer.status != FileTransferStatus.Cancelled)
                            {
                                fileTransferContainer.status = FileTransferStatus.Error;
                            }
                        }
                    }
                }
                catch {
                    lock (RunningTransfers) {
                        if (fileTransferContainer.status != FileTransferStatus.Cancelled)
                        {
                            fileTransferContainer.status = FileTransferStatus.Error;
                        }
                    }
                }
            }
        }
Пример #3
0
        internal bool managedReceiveFileOverSockets(string filePath, long length)
        {
            short _count = 0;
            long  _index = 0;
            int   _size  = 1;

            Thread _thread = new Thread(() => monitorControlChannel());

            _thread.Name         = "Control Socket monitor for " + dataSocket.RemoteEndPoint.ToString();
            _thread.IsBackground = true;
            _thread.Start();

            try {
                using (FileStream _fs = new FileStream(filePath + ".temp", FileMode.CreateNew)) {
                    _fs.SetLength(length);
                    byte[] _buffer;

                    while (dataSocket.Connected && controlSocket.Connected && _index < length)
                    {
                        if (fileTransferContainer.status == FileTransferStatus.Paused)
                        {
                            resetEvent.WaitOne();
                        }
                        if (!NetworkCommunicationManagers.ReceiveIntOverSocket(dataSocket, out _size))
                        {
                            continue;
                        }
                        ;
                        _buffer = new byte[_size];
                        if (!NetworkCommunicationManagers.ReceiveByteArrayOverSocket(dataSocket, out _buffer, _size))
                        {
                            continue;
                        }
                        ;


                        _fs.Position = _index;
                        _fs.Write(_buffer, 0, _buffer.Length);
                        _index += _size;
                        _count++;
                        if (_count % 200 == 0)
                        {
                            lock (RunningTransfers) {
                                if (Math.Round(((((double)_index / length) * 100) - fileTransferContainer.progress), 1) >= 0.1)
                                {
                                    fileTransferContainer.progress = (float)Math.Round((((double)_index / length) * 100), 1);
                                }
                            }
                            _count = 0;
                            ThreadPool.QueueUserWorkItem(state => {
                                lock (controlSocket) {
                                    NetworkCommunicationManagers.SendByteArrayOverSocket(controlSocket, new byte[] { (byte)FileTransferCommands.BlockTransferred });
                                }
                            });
                        }
                    }
                }
                lock (controlSocket) {
                    NetworkCommunicationManagers.SendByteArrayOverSocket(controlSocket, new byte[] { (byte)FileTransferCommands.EndTransfer });
                }
            }
            catch (ObjectDisposedException) {
                NetworkCommunicationManagers.Disconnect(controlSocket);
                NetworkCommunicationManagers.Disconnect(dataSocket);
            }
            catch (SocketException) {
                NetworkCommunicationManagers.Disconnect(controlSocket);
                NetworkCommunicationManagers.Disconnect(dataSocket);
            }

            if (_index < length)
            {
                try {
                    File.Delete(filePath + ".temp");
                }
                catch { }
                lock (RunningTransfers) {
                    if (fileTransferContainer.status != FileTransferStatus.Cancelled)
                    {
                        fileTransferContainer.status = FileTransferStatus.Error;
                    }
                }
                return(false);
            }
            else
            {
                try {
                    File.Move(filePath + ".temp", filePath);
                }
                catch (IOException) {
                    try {
                        File.Delete(filePath + ".temp");
                    }
                    catch { }
                }
                lock (RunningTransfers) {
                    fileTransferContainer.status   = FileTransferStatus.Finished;
                    fileTransferContainer.progress = 100;
                }
            }
            return(true);
        }
Пример #4
0
        internal void monitorControlChannel()
        {
            try {
                byte[] arr;
                FileTransferCommands _command;
                while (controlSocket.Connected)
                {
                    if (!NetworkCommunicationManagers.ReceiveByteArrayOverSocket(controlSocket, out arr, 1))
                    {
                        continue;
                    }
                    _command = (FileTransferCommands)arr[0];
                    switch (_command)
                    {
                    case FileTransferCommands.BlockTransferred:
                        lock (syncObject) {
                            acknowledgedTransfers++;
                        }
                        break;

                    case FileTransferCommands.EndTransfer:
                        NetworkCommunicationManagers.Disconnect(controlSocket);
                        NetworkCommunicationManagers.Disconnect(dataSocket);
                        return;

                    case FileTransferCommands.Pause:
                        lock (RunningTransfers) {
                            fileTransferContainer.status = FileTransferStatus.Paused;

                            if (fileTransferContainer.pausedBy == PausedBy.None)
                            {
                                fileTransferContainer.pausedBy = PausedBy.OtherPeer;
                            }
                            else if (fileTransferContainer.pausedBy == PausedBy.User)
                            {
                                fileTransferContainer.pausedBy = PausedBy.Both;
                            }
                        }

                        ThreadPool.QueueUserWorkItem(state => {
                            lock (controlSocket) {
                                NetworkCommunicationManagers.SendByteArrayOverSocket(controlSocket, new byte[] { (byte)FileTransferCommands.PauseOrResumeRequestReceived });
                            }
                        });

                        break;

                    case FileTransferCommands.PauseOrResumeRequestReceived:
                        lock (RunningTransfers) {
                            if (fileTransferContainer.transferType == FileTransferType.Upload)
                            {
                                if (fileTransferContainer.status == FileTransferStatus.Paused && fileTransferContainer.pausedBy == PausedBy.None)
                                {
                                    fileTransferContainer.status = FileTransferStatus.Running;
                                    resetEvent.Set();
                                }
                            }
                            else if (fileTransferContainer.transferType == FileTransferType.Download)
                            {
                                if (fileTransferContainer.pausedBy != PausedBy.None && fileTransferContainer.status == FileTransferStatus.Running)
                                {
                                    fileTransferContainer.status = FileTransferStatus.Paused;
                                }
                            }
                        }
                        break;

                    case FileTransferCommands.Resume:
                        lock (RunningTransfers) {
                            if (fileTransferContainer.pausedBy == PausedBy.OtherPeer)
                            {
                                fileTransferContainer.pausedBy = PausedBy.None;
                                fileTransferContainer.status   = FileTransferStatus.Running;
                                resetEvent.Set();
                            }
                            else if (fileTransferContainer.pausedBy == PausedBy.Both)
                            {
                                fileTransferContainer.pausedBy = PausedBy.User;
                            }

                            ThreadPool.QueueUserWorkItem(state => {
                                lock (controlSocket) {
                                    NetworkCommunicationManagers.SendByteArrayOverSocket(controlSocket, new byte[] { (byte)FileTransferCommands.PauseOrResumeRequestReceived });
                                }
                            });
                        }
                        break;
                    }
                }
            }
            catch (ObjectDisposedException) {}
            catch (SocketException) {}
            finally {
                NetworkCommunicationManagers.Disconnect(controlSocket);
                NetworkCommunicationManagers.Disconnect(dataSocket);
            }
        }