159 lines · 5.0 KB · C#
RawDownload
//******************************************************************************************************//  UdpChannel.cs - Gbtc////  Copyright © 2020, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this//  file except in compliance with the License. You may obtain a copy of the License at:////      http://opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  05/12/2020 - J. Ritchie Carroll//       Generated original version of source code.////****************************************************************************************************** #region [ Contributor License Agreements ] //*******************************************************************************************************////   Code based on the following project://        https://github.com/Callisto82/tftp.net//  //   Copyright © 2011, Michael Baer////******************************************************************************************************* #endregion using System;using System.Net.Sockets;using System.Net;using System.IO;using GSF.Net.TFtp.Commands; namespace GSF.Net.TFtp.Channel{    internal class UdpChannel : ITransferChannel    {        public event TFtpCommandHandler OnCommandReceived;        public event TFtpChannelErrorHandler OnError;         private IPEndPoint m_endpoint;        private UdpClient m_client;        private readonly CommandSerializer m_serializer = new CommandSerializer();        private readonly CommandParser m_parser = new CommandParser();         public UdpChannel(UdpClient client)        {            m_client = client;            m_endpoint = null;        }         public void Open()        {            if (m_client == null)                throw new ObjectDisposedException(nameof(UdpChannel));             m_client.BeginReceive(UdpReceivedCallback, null);        }         private void UdpReceivedCallback(IAsyncResult result)        {            IPEndPoint endpoint = new IPEndPoint(0, 0);            ITFtpCommand command = null;             try            {                byte[] data;                 lock (this)                {                    if (m_client == null)                        return;                     data = m_client.EndReceive(result, ref endpoint);                }                 command = m_parser.Parse(data);            }            catch (SocketException e)            {                // Handle receive error                RaiseOnError(new NetworkError(e));            }            catch (TFtpParserException e2)            {                // Handle parser error                RaiseOnError(new NetworkError(e2));            }             if (command != null)                RaiseOnCommand(command, endpoint);             lock (this)            {                m_client?.BeginReceive(UdpReceivedCallback, null);            }        }         private void RaiseOnCommand(ITFtpCommand command, IPEndPoint endpoint)        {            OnCommandReceived?.Invoke(command, endpoint);        }         private void RaiseOnError(TFtpTransferError error)        {            OnError?.Invoke(error);        }         public void Send(ITFtpCommand command)        {            if (m_client == null)                throw new ObjectDisposedException(nameof(UdpChannel));             if (m_endpoint == null)                throw new InvalidOperationException("RemoteEndpoint needs to be set before you can send TFTP commands.");             using (MemoryStream stream = new MemoryStream())            {                m_serializer.Serialize(command, stream);                byte[] data = stream.GetBuffer();                m_client.Send(data, (int)stream.Length, m_endpoint);            }        }         public void Dispose()        {            lock (this)            {                if (m_client == null)                    return;                 m_client.Close();                m_client = null;            }        }         public EndPoint RemoteEndpoint        {            get => m_endpoint;             set            {                if (m_client == null)                    throw new ObjectDisposedException(nameof(UdpChannel));                 m_endpoint = value as IPEndPoint ?? throw new NotSupportedException("UdpChannel can only connect to IPEndPoints.");            }        }    }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t