/// <summary> /// Called by a session to remove itself when it's no longer needed /// </summary> /// <param name="tftpSession">The session to remove</param> internal void UnregisterSession(TftpSession tftpSession) { if (!Sessions.TryRemove(tftpSession.RemoteHost, out TftpSession removedSession)) { throw new Exception("Could not remove session " + tftpSession.RemoteHost.ToString() + " from known sessions"); } }
/// <summary> /// Handle the incoming UDP packet /// </summary> public void OnUdpData(IPEndPoint source, byte[] messageData) { try { if (!Sessions.TryGetValue(source, out TftpSession session)) { LogDebug($"New client detected from {source.Address}:{source.Port}"); session = new TftpSession(this, source); Sessions[source] = session; } Task.Factory.StartNew( async() => { try { await session.OnReceiveAsync(messageData); } catch (Exception e) { LogError("Internal error: " + e.Message); } } ); } catch (Exception e) { LogError("Internal error: " + e.Message); } }
private void EmitSessionError(TftpSession session, string reason) { EventHandler <TftpTransferErrorEventArgs> handler = (session.Operation == ETftpOperationType.WriteOperation) ? FileReceiveError : FileTransmitError ; var eventArgs = new TftpTransferErrorEventArgs { Id = session.Id, Operation = session.Operation, Filename = session.Filename, RemoteHost = session.RemoteHost, Stream = (session.Operation == ETftpOperationType.WriteOperation) ? (MemoryStream)session.TransferStream : null, TransferInitiated = session.TransferRequestInitiated, TransferCompleted = DateTimeOffset.Now, Transferred = session.Position, FailureReason = reason }; handler?.Invoke( this, eventArgs ); var invocationList = (session.Operation == ETftpOperationType.WriteOperation) ? (FileReceiveErrorAsync?.GetInvocationList()) : (FileTransmitErrorAsync?.GetInvocationList()) ; if (invocationList == null) { return; } var handlerTasks = new Task[invocationList.Length]; for (int i = 0; i < invocationList.Length; i++) { handlerTasks[i] = ((Func <object, TftpTransferErrorEventArgs, Task>)invocationList[i])(this, eventArgs); } Task.WhenAll(handlerTasks); }
private void OnUdpData(IAsyncResult result) { var timeReceived = DateTimeOffset.Now; var socket = result.AsyncState as UdpClient; try { IPEndPoint source = new IPEndPoint(0, 0); var messageData = socket.EndReceive(result, ref source); if (!Sessions.TryGetValue(source, out TftpSession session)) { LogDebug($"New client detected from {source.Address}:{source.Port}"); session = new TftpSession(this, source); Sessions[source] = session; } var receiveTask = Task.Factory.StartNew( async() => { try { await session.OnReceiveAsync(messageData); } catch (Exception e) { LogError("Internal error: " + e.Message); } } ); } catch (Exception e) { LogError("Internal error: " + e.Message); } socket.BeginReceive(new AsyncCallback(OnUdpData), socket); }
/// <summary> /// Called by a session to signal that it's complete /// </summary> /// <param name="session">The transfer which is complete</param> internal async Task TransferCompleteAsync(TftpSession session) { UnregisterSession(session); EventHandler <TftpTransferCompleteEventArgs> handler = (session.Operation == ETftpOperationType.WriteOperation) ? FileReceived : FileTransmitted ; var eventArgs = new TftpTransferCompleteEventArgs { Id = session.Id, Operation = session.Operation, Filename = session.Filename, RemoteHost = session.RemoteHost, Stream = (session.Operation == ETftpOperationType.WriteOperation) ? (MemoryStream)session.TransferStream : null, TransferInitiated = session.TransferRequestInitiated, TransferCompleted = DateTimeOffset.Now, Transferred = session.Position }; handler?.Invoke( this, eventArgs ); var invocationList = (session.Operation == ETftpOperationType.WriteOperation) ? (FileReceivedAsync?.GetInvocationList()) : (FileTransmittedAsync?.GetInvocationList()) ; if (invocationList == null) { return; } var handlerTasks = new Task[invocationList.Length]; for (int i = 0; i < invocationList.Length; i++) { handlerTasks[i] = ((Func <object, TftpTransferCompleteEventArgs, Task>)invocationList[i])( this, new TftpTransferCompleteEventArgs { Id = session.Id, Operation = session.Operation, Filename = session.Filename, RemoteHost = session.RemoteHost, Stream = (session.Operation == ETftpOperationType.WriteOperation) ? (MemoryStream)session.TransferStream : null, TransferInitiated = session.TransferRequestInitiated, TransferCompleted = DateTimeOffset.Now, Transferred = session.Position } ); } await Task.WhenAll(handlerTasks); }