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); }
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)); }
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); } }