Пример #1
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);
        }
Пример #2
0
        internal bool AcceptFileTransfer(Socket socket, int port1, MainWindow mainWindow)
        {
            int             _port2;
            SocketException _socketException;

            if (!NetworkCommunicationManagers.ConnectToEndPoint(port1, socket.RemoteEndPoint.ToString().Remove(socket.RemoteEndPoint.ToString().LastIndexOf(':')), out dataSocket, out _socketException))
            {
                return(false);
            }

            NetworkCommunicationManagers.ReceiveIntOverSocket(dataSocket, out _port2);

            if (!NetworkCommunicationManagers.ConnectToEndPoint(_port2, socket.RemoteEndPoint.ToString().Remove(socket.RemoteEndPoint.ToString().LastIndexOf(':')), out controlSocket, out _socketException))
            {
                return(false);
            }

            fileTransferContainer.FileTransferClassInstance = this;

            byte[] _buffer = null;
            int    _temp;
            long   _size;
            string _filename;

            try {
                NetworkCommunicationManagers.ReceiveIntOverSocket(dataSocket, out _temp);
                NetworkCommunicationManagers.ReceiveByteArrayOverSocket(dataSocket, out _buffer, _temp);
            }
            catch (ObjectDisposedException) {
                NetworkCommunicationManagers.Disconnect(dataSocket);
                NetworkCommunicationManagers.Disconnect(controlSocket);
                return(false);
            }
            catch (SocketException) {
                NetworkCommunicationManagers.Disconnect(dataSocket);
                NetworkCommunicationManagers.Disconnect(controlSocket);
                return(false);
            }

            unpackFileMetadata(_buffer, out _filename, out _size);

            fileTransferContainer.fileName    = _filename;
            fileTransferContainer.sizeInBytes = _size;
            fileTransferContainer.size        = Converters.DataConverter.bytesToReadableString(_size);

            if (_size > mainWindow.maxAcceptedFileSizeWithoutConfirmation)
            {
                ManualResetEvent _replyRecieved           = new ManualResetEvent(false);
                System.Windows.MessageBoxResult _continue = System.Windows.MessageBoxResult.No;
                mainWindow.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => {
                    Thread.Sleep(1000);
                    _continue = System.Windows.MessageBox.Show("Receive file \"" + _filename + "\" from " + socket.RemoteEndPoint.ToString().Remove(socket.RemoteEndPoint.ToString().LastIndexOf(':')) + " (Size: " + _size + " bytes)", "File Transfer", System.Windows.MessageBoxButton.YesNo);
                    _replyRecieved.Set();
                }));
                _replyRecieved.WaitOne();
                _replyRecieved.Dispose();
                if (_continue != System.Windows.MessageBoxResult.Yes)
                {
                    mainWindow.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => {
                        lock (RunningTransfers) {
                            RunningTransfers.Remove(fileTransferContainer);
                        }
                    }));
                    NetworkCommunicationManagers.Disconnect(dataSocket);
                    NetworkCommunicationManagers.Disconnect(controlSocket);
                    return(false);
                }
            }

            if (!Directory.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads", "ChatApp")))
            {
                Directory.CreateDirectory(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads", "ChatApp"));
            }
            ;

            string _filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads", "ChatApp", _filename);

            if (File.Exists(_filePath))
            {
                string _extension, _assignedFilename;
                if (_filename.LastIndexOf('.') == -1)
                {
                    _extension        = "";
                    _assignedFilename = _filename;
                }
                else
                {
                    _extension        = "." + _filename.Remove(0, _filename.LastIndexOf('.') + 1);
                    _assignedFilename = _filename.Remove(_filename.Length - _extension.Length, _extension.Length);
                }

                for (int i = 0; true; i++)
                {
                    _filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads", "ChatApp", _assignedFilename + "(" + i + ")" + _extension);
                    if (!File.Exists(_filePath))
                    {
                        break;
                    }
                }
            }

            fileTransferContainer.filePath = _filePath;

            return(managedReceiveFileOverSockets(_filePath, _size));
        }
Пример #3
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);
            }
        }