async Task IShutdownSource.Shutdown() { tokenSource.Cancel(); Cleanup?.Invoke(this, EventArgs.Empty); await Task.WhenAll(cleanupTasks.Select(IgnoreTimeout)); Phase2Cleanup?.Invoke(this, EventArgs.Empty); }
private static unsafe void OnUnhandledException(object sender, UnhandledExceptionEventArgs eventArgs) { var st = new StackTrace(1, true); Console.Error.WriteLine("Unhandled Exception Entry Stack:"); Console.Error.WriteLine(st.ToString()); st = new StackTrace((Exception)eventArgs.ExceptionObject, 0, true); Console.Error.WriteLine("Unhandled Exception:"); Console.Error.WriteLine(st.ToString()); if (eventArgs.IsTerminating) { Cleanup?.Invoke(); } }
/// <summary> /// Receiving file on specified ip and port. It will start listening for a connection /// and will stop listening after the transfer. /// </summary> /// <param name="ip">Local ip address to listen on</param> /// <param name="port">Local port to listen on</param> /// <param name="destinationFolder">Folder where the recieved file is going to be saved to</param> public void ReceiveFile(IPAddress ip, int port, string destinationFolder) { // lock to prevent bad things in case buffer size is changed lock (_lockReceiving) { try { // Reset progress and update status _progress = 0; ProgressPercent?.Invoke(this, _progress); // Listen for incoming coonnections var listener = new TcpListener(ip, port); listener.Start(); // Update status StatusMessage?.Invoke(this, $"Listening on {ip}:{port}"); try { while (true) { using (var client = listener.AcceptTcpClient()) using (var stream = client.GetStream()) { client.ReceiveBufferSize = BufferSize; StatusMessage?.Invoke(this, "Receiving file..."); byte[] buffer = new byte[BufferSize]; // Get file info from first packet int bytesRead = stream.Read(buffer, 0, buffer.Length); // Header: 4 bytes for file length (int) + 4 bytes for file name length (int) + fileName + 20 bytes checksum int headerOffset = 0; int fileLen = BitConverter.ToInt32(buffer, headerOffset); headerOffset += sizeof(int); int fileNameLen = BitConverter.ToInt32(buffer, headerOffset); headerOffset += sizeof(int); string fileName = Encoding.ASCII.GetString(buffer, headerOffset, fileNameLen); headerOffset += fileNameLen; byte[] checksumByte = new byte[20]; Array.Copy(buffer, headerOffset, checksumByte, 0, checksumByte.Length); headerOffset += checksumByte.Length; bool checksumAvailable = !checksumByte.All(singleByte => singleByte == 0); // Update status and progress and calculate progress percent increment StatusMessage?.Invoke(this, $"Receiving {fileName} on {ip}:{port} from {client.Client.RemoteEndPoint}"); double progressBarIncrement = 100.0 / (Convert.ToDouble(fileLen) / BufferSize); int progressSingleIncrement = 0; _progress += progressBarIncrement; ProgressPercent?.Invoke(this, _progress); // Create file to safe incoming data to using (var output = File.Create(Path.Combine(destinationFolder, fileName))) { output.Write(buffer, headerOffset, bytesRead - headerOffset); if (bytesRead >= buffer.Length) { while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) { output.Write(buffer, 0, bytesRead); // Update progress only every percent _progress += progressBarIncrement; if (!(_progress > progressSingleIncrement + 1)) { continue; } progressSingleIncrement = Convert.ToInt32(_progress); ProgressPercent?.Invoke(this, progressSingleIncrement); } } } StatusMessage?.Invoke(this, "File received"); if (checksumAvailable) { StatusMessage?.Invoke(this, "File received - Calculating checksum..."); using (var fileStream = new BufferedStream(File.OpenRead(Path.Combine(destinationFolder, fileName)), 32768)) { SHA1Managed sha = new SHA1Managed(); byte[] checksumByteCalc = sha.ComputeHash(fileStream); string checksumCalc = BitConverter.ToString(checksumByteCalc).Replace("-", String.Empty).ToLower(); string checksumSent = BitConverter.ToString(checksumByte).Replace("-", String.Empty).ToLower(); Debug.WriteLine($"sent: {checksumSent} | calc: {checksumCalc}"); if (!Enumerable.SequenceEqual(checksumByte, checksumByteCalc)) { ChecksumError?.Invoke(this, $"sent: {checksumSent} != calc: {checksumCalc}"); StatusMessage?.Invoke(this, $"Checksum missmatch\nSent: {checksumSent}\nCalc: {checksumCalc}"); } else { StatusMessage?.Invoke(this, $"Checksum match\nSent: {checksumSent}\nCalc: {checksumCalc}"); } } } // Raise new file received event NewFileReceived?.Invoke(this, fileName); ProgressPercent?.Invoke(this, 100); } break; } } finally { // Stop listening listener.Stop(); } } catch (Exception ex) { Debug.WriteLine(ex); StatusMessage?.Invoke(this, ex.Message); } finally { // Send cleanup event, e.g. usefull to enable buttens again Cleanup?.Invoke(this, EventArgs.Empty); } } }
/// <summary> /// Sends a file with header composed of file size and file name /// </summary> /// <param name="ip">Receiving end ip address</param> /// <param name="port">Receiving end port</param> /// <param name="filePath">Full path to file</param> public void SendFile(IPAddress ip, int port, string filePath, bool checksum = false) { // lock to prevent bad things in case buffer size is changed lock (_lockSending) { try { // Reset progress and update status _progress = 0; ProgressPercent?.Invoke(this, _progress); StatusMessage?.Invoke(this, "Connecting..."); // Open socket using (Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { // Get file info // Header: 4 bytes for file length (int) + 4 bytes for file name length (int) + fileName + 20 bytes checksum FileInfo fi = new FileInfo(filePath); byte[] fileLen = BitConverter.GetBytes((int)fi.Length); byte[] fileNameByte = Encoding.ASCII.GetBytes(Path.GetFileName(filePath)); byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length); byte[] checksumByte = new byte[20]; // SHA1 checksum is byte[20] byte[] header = new byte[fileLen.Length + fileNameLen.Length + fileNameByte.Length + checksumByte.Length]; if (checksum) { using (var stream = new BufferedStream(File.OpenRead(filePath), 32768)) { SHA1Managed sha = new SHA1Managed(); checksumByte = sha.ComputeHash(stream); Debug.WriteLine(BitConverter.ToString(checksumByte).Replace("-", String.Empty).ToLower()); } } // Copy data into send byte array int headerOffset = 0; fileLen.CopyTo(header, headerOffset); headerOffset += fileLen.Length; fileNameLen.CopyTo(header, headerOffset); headerOffset += fileNameLen.Length; fileNameByte.CopyTo(header, headerOffset); headerOffset += fileNameByte.Length; checksumByte.CopyTo(header, headerOffset); // Connect to end point IPEndPoint ipEndPoint = new IPEndPoint(ip, port); soc.SendBufferSize = BufferSize; soc.Connect(ipEndPoint); // Update status and calculate progress percent increment StatusMessage?.Invoke(this, $"Sending {Path.GetFileName(filePath)} to {ip}:{port} from {soc.LocalEndPoint}"); double progressBarIncrement = 100.0 / (Convert.ToDouble(fi.Length) / BufferSize); int progressSingleIncrement = 0; using (FileStream fsSource = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { int numBytesToRead = (int)fsSource.Length; // Initial packet var firstPacket = (int)fi.Length >= BufferSize ? new byte[BufferSize] : new byte[header.Length + (int)fi.Length]; header.CopyTo(firstPacket, 0); // Fill rest of first packet up with file data int transmitOffset = fsSource.Read(firstPacket, header.Length, firstPacket.Length - header.Length); // Send initial packet soc.Send(firstPacket, firstPacket.Length, SocketFlags.None); _progress += progressBarIncrement; // Transmit data in buffer size chunks if (transmitOffset >= BufferSize - header.Length) { byte[] buffer = new byte[BufferSize]; while (true) { // Calculate remaining bytes to send int sendsize = numBytesToRead - transmitOffset; // Send buffer sized chunk if enough data is left, otherwise send remaining bytes if (sendsize > BufferSize) { sendsize = BufferSize; } fsSource.Read(buffer, 0, sendsize); soc.Send(buffer, sendsize, SocketFlags.None); transmitOffset += sendsize; // Update progress only every percent _progress += progressBarIncrement; if (_progress > progressSingleIncrement + 1) { progressSingleIncrement = Convert.ToInt32(_progress); ProgressPercent?.Invoke(this, progressSingleIncrement); } if (transmitOffset >= numBytesToRead) { break; } } } } // Closing socket soc.Shutdown(SocketShutdown.Both); soc.Close(); StatusMessage?.Invoke(this, "File sent"); ProgressPercent?.Invoke(this, 100); } } catch (Exception ex) { Debug.WriteLine(ex.Message); StatusMessage?.Invoke(this, ex.Message); } finally { // Send cleanup event, e.g. usefull to enable buttens again Cleanup?.Invoke(this, EventArgs.Empty); } } }
public void RemoveBenchmarkFiles() { Cleanup.Invoke(this); }
public void Dispose() { Cleanup?.Invoke(); Container.Dispose(); }
public void Dispose() { Cleanup?.Invoke(); ServiceProvider?.Dispose(); }