Ejemplo n.º 1
0
        /// <summary>
        /// Erzeugen des Datenkanals.
        /// </summary>
        /// <param name="result">Aktuelle Informationen zum zugehörigen Steuerkanal.</param>
        private void OnAcceptPassive(IAsyncResult result)
        {
            // Report
            FTPMain.Log("OnAcceptPassive");

            // We are terminating
            if (null == m_Passive)
            {
                return;
            }

            // What to do
            Processor processor;

            // Synchronize
            lock (m_DataLock)
            {
                // Get the communication socket
                m_Data = new DataChannel(m_Passive.EndAccept(result), OnDataChannelFinished);

                // Load processor
                processor = m_DelayedProcessor;

                // Reset
                m_DelayedProcessor = null;
            }

            // Nothing to do
            if (null != processor)
            {
                processor(m_DelayedCommand);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Scließt einen <see cref="Socket"/>.
        /// </summary>
        /// <param name="socket">Die Netzwerkverbindung.</param>
        /// <param name="shutdown">Gesetzt, wenn ein <see cref="Socket.Shutdown"/> ausgeführt werden soll (nicht
        /// für Steuerkanäle).</param>
        /// <returns>Gesetzt, wenn die Netzwerkverbindung tatsächlich geschlossen wurde.</returns>
        private bool Close(ref Socket socket, bool shutdown)
        {
            // Report
            FTPMain.Log("FTPClient closing");

            // Start cleanup
            using (Socket cleanup = socket)
                if (null != cleanup)
                {
                    // Forget
                    socket = null;

                    // Close
                    if (shutdown)
                    {
                        cleanup.Shutdown(SocketShutdown.Both);
                    }
                    cleanup.Close();

                    // Did it
                    return(true);
                }

            // Did nothing
            return(false);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Beendet die Nutzung dieses Datenkanals endgültig.
        /// </summary>
        private void Close()
        {
            // Report
            FTPMain.Log("DataChannel closing");

            // Process
            using (Socket cleanup = m_Socket)
                if (null != cleanup)
                {
                    // Wipe out
                    m_Socket = null;

                    // Shutdown
                    cleanup.Shutdown(SocketShutdown.Both);
                    cleanup.Close();

                    // Report
                    if (null != m_OnFinished)
                    {
                        m_OnFinished(this);
                    }
                }

            // Check file
            using (Stream file = m_File)
                if (null != file)
                {
                    // Forget
                    m_File = null;

                    // Close
                    file.Close();
                }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Erkennt das Ende des Versendens eines Stücks aus einer Datei.
        /// </summary>
        /// <param name="result">Informationen zum Ergebnis des Versendens.</param>
        private void FinishChunk(IAsyncResult result)
        {
            // Report
            FTPMain.Log("FinishChunk");

            // Be safe
            try
            {
                // Attach to socket
                Socket socket = (Socket)result.AsyncState;

                // Terminate request
                socket.EndSend(result);

                // Send next chunk
                if (m_Abort.WaitOne(0, false))
                {
                    // Stop right now
                    Close();
                }
                else
                {
                    // Continue with next chunk
                    Send(m_File);
                }
            }
            catch
            {
                // Close all
                Close();
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Beendet dieses Datenkanal vorzeitig.
        /// </summary>
        public void Abort()
        {
            // Report
            FTPMain.Log("DataChannel aborted");

            // Signal the very end
            m_Abort.Set();
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Beendet den Datenkanal.
        /// </summary>
        public void Abort()
        {
            // Report
            FTPMain.Log("FTPClient aborting");

            // Synchronized
            lock (m_DataLock)
                if (null != m_Data)
                {
                    m_Data.Abort();
                }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Schließt den Datenkanal.
        /// </summary>
        private void CloseData()
        {
            // Report
            FTPMain.Log("CloseData");

            // Reset
            m_DelayedProcessor = null;

            // Start cleanup data channel
            lock (m_DataLock)
                using (DataChannel cleanup = m_Data)
                    m_Data = null;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Erzeugt eine neue Datenkanalinstanz.
        /// </summary>
        /// <param name="socket">Der zugehörige Datenkanal.</param>
        /// <param name="onFinished">Methode, die nach dem Schliessen des Datenkanals aufgerufen werden soll.</param>
        public DataChannel(Socket socket, FinishedHandler onFinished)
        {
            // Remember
            m_OnFinished = onFinished;

            // Attach to socket
            m_Socket = socket;

            // Use asynchronous
            m_Socket.Blocking = false;

            // Report
            FTPMain.Log("DataChannel created");
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Schließt die Verbindung zum Client.
        /// </summary>
        public void Close()
        {
            // Report
            FTPMain.Log("FTPClient Close() called");

            // Close passive socket
            ClosePassive();

            // Start cleanup
            if (Close(ref m_Socket, true))
            {
                if (null != m_OnFinished)
                {
                    m_OnFinished(this);
                }
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Meldet das Ergebnis einer Operation.
        /// </summary>
        /// <param name="toSend">Die zu übermittelnden Daten.</param>
        /// <returns>Informationen zum gestarteten Netzwerkvorgang.</returns>
        private IAsyncResult Send(byte[] toSend)
        {
            // Be safe
            try
            {
                // Report
                FTPMain.Log("FTPClient started to send {0} bytes", toSend.Length);

                // Start
                return(m_Socket.BeginSend(toSend, 0, toSend.Length, SocketFlags.None, OnSendCompleteControl, null));
            }
            catch
            {
                // In error
                return(null);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Wird vom Datenkanal <see cref="DataChannel"/> aufgerufen, sobald alle Daten übertragen wurden.
        /// </summary>
        /// <param name="data">Der abgeschlossene Datenkanal.</param>
        private void OnDataChannelFinished(DataChannel data)
        {
            // Report
            Send(226, "Transfer Complete");

            // Terminate on empty file
            if (!data.GotData)
            {
                // Report
                FTPMain.Log("Detected empty File");

                // Remember
                m_EmptyFile = true;

                // Terminate
                Close();
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Das übermitteln der Nachricht wurde abgeschlossen.
        /// </summary>
        /// <param name="result">Ergebnis zur gerade abgeschlossenen Operation.</param>
        private void OnSendCompleteControl(IAsyncResult result)
        {
            // Report
            FTPMain.Log("OnSendCompleteControl");

            // Be safe
            try
            {
                // Finish
                m_Socket.EndSend(result);

                // Primary communication
                m_Socket.BeginReceive(m_Buffer, 0, m_Buffer.Length, SocketFlags.None, OnReceive, null);
            }
            catch
            {
                // All done
                Close();
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Versendet eine Zeichenkette über den Datenkanal.
        /// </summary>
        /// <param name="text">Der Inhalt der zu verwendenden Zeichenkette.</param>
        public void Send(string text)
        {
            // Report
            FTPMain.Log("Send {0}", text);

            // To byte array
            byte[] toSend = Encoding.Default.GetBytes(text);

            // Be safe
            try
            {
                // Start sending
                m_Socket.BeginSend(toSend, 0, toSend.Length, SocketFlags.None, FinishString, m_Socket);
            }
            catch
            {
                // Terminate on any error
                Close();
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Erkennt das Ende des Versendens einer Zeichenkette.
        /// </summary>
        /// <param name="result">Informationen über das Ergebnis des Versendens.</param>
        private void FinishString(IAsyncResult result)
        {
            // Report
            FTPMain.Log("FinishString");

            // Be safe
            try
            {
                // Attach to socket
                Socket socket = (Socket)result.AsyncState;

                // Terminate request
                socket.EndSend(result);
            }
            catch
            {
                // Ignore any error
            }

            // Close all
            Close();
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Es wurde ein FTP Befehl empfangen.
        /// </summary>
        /// <param name="result">Informationen zu den Daten des Befehls.</param>
        private void OnReceive(IAsyncResult result)
        {
            // Report
            FTPMain.Log("OnReceive");

            // Already done
            if (null == m_Socket)
            {
                // Report
                FTPMain.Log("! No socket");

                // Done
                return;
            }

            // The command
            string command;

            // Be safe
            try
            {
                // Get data
                int bytes = m_Socket.EndReceive(result);

                // Report
                FTPMain.Log("Received {0} Bytes", bytes);

                // Finished
                if (bytes < 1)
                {
                    // Terminate
                    Close();

                    // Done
                    return;
                }

                // Get the command
                command = Encoding.Default.GetString(m_Buffer, 0, bytes);

                // Report
                FTPMain.Log("Received Command {0}", command);
            }
            catch
            {
                // Terminate
                Close();

                // Done
                return;
            }

            // Report
            Debug.Write(string.Format("{1}:{2} {0}", command, Thread.CurrentThread.ManagedThreadId, DateTime.Now.Ticks));

            // Dispatch
            string key = command.Split(' ', '\r', '\n')[0];

            // Process
            Processor processor;

            if (m_Processors.TryGetValue(key, out processor))
            {
                processor(command.Substring(4, command.Length - 6).Trim());
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Sendet die nächsten Bytes der angegebenen Datei über den Datenkanal. Wurde dieser Teil
        /// erfolgreich verschickt, dann wird der nächste Teil abgerufen.
        /// </summary>
        /// <param name="file">Zu versendende Datei.</param>
        public void Send(Stream file)
        {
            // Report
            FTPMain.Log("Send Stream");

            // At least we tried
            if (!m_GotData.HasValue)
            {
                m_GotData = false;
            }

            // Create buffer
            if (null == m_Buffer)
            {
                m_Buffer = new byte[100000];
            }

            // May retry - give us 30 seconds to detect end of live recording
            for (int retry = FTPMain.ShutdownDelay; retry-- > 0;)
            {
                // Report
                FTPMain.Log("Awaiting Data");

                // Read bytes
                int bytes = file.Read(m_Buffer, 0, m_Buffer.Length);

                // Report
                FTPMain.Log("Got {0} Bytes", bytes);

                // Wait a bit
                if (bytes < 1)
                {
                    // Delay
                    if (m_Abort.WaitOne(1000, true))
                    {
                        break;
                    }

                    // Next
                    continue;
                }

                // Report
                FTPMain.ReportDataFromFile(bytes);

                // At least anything
                m_GotData = true;

                // Restart retry counter
                retry = FTPMain.ShutdownDelay;

                // Try to send this chunk
                try
                {
                    // Remember file for next chunk
                    m_File = file;

                    // Try to send
                    m_Socket.BeginSend(m_Buffer, 0, bytes, SocketFlags.None, FinishChunk, m_Socket);

                    // Report
                    FTPMain.Log("BeginSend {0} called", bytes);

                    // Wait for next chunk
                    return;
                }
                catch
                {
                    // Terminate on any error
                    break;
                }
            }

            // Terminate
            Close();
        }