Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 插座在关闭时能发出信号吗?_C++_Sockets_Network Programming_Signals - Fatal编程技术网

C++ 插座在关闭时能发出信号吗?

C++ 插座在关闭时能发出信号吗?,c++,sockets,network-programming,signals,C++,Sockets,Network Programming,Signals,我正在编写某种服务器应用程序(用C++编写),其中包含服务器正在与之通信的套接字的一组文件描述符,我希望知道它们中的一个在另一端何时关闭,而不必读/写。我经常阻塞select()(没有超时),等待读取准备就绪和我提供给它的两个fd_集的异常情况 我一开始以为,在另一侧关闭的任何插座都会出现在例外FD中,但当我继续阅读时,我开始明白,情况并非如此。报告并没有说太多关于FD之外的例外情况正在被关注。此外,据我所知,什么是异常情况(我自己使用的是Ubnubt 11.10),我没有发现任何地方引用正在关

我正在编写某种服务器应用程序(用C++编写),其中包含服务器正在与之通信的套接字的一组文件描述符,我希望知道它们中的一个在另一端何时关闭,而不必读/写。我经常阻塞select()(没有超时),等待读取准备就绪和我提供给它的两个fd_集的异常情况

我一开始以为,在另一侧关闭的任何插座都会出现在例外FD中,但当我继续阅读时,我开始明白,情况并非如此。报告并没有说太多关于FD之外的例外情况正在被关注。此外,据我所知,什么是异常情况(我自己使用的是Ubnubt 11.10),我没有发现任何地方引用正在关闭/关闭(另一侧)的套接字作为异常

此外,还提到了插座可能发送的两种信号:

  • SIGPIPE-写入关闭的套接字时发送
  • SIGIO-在发生I/O事件时发送
  • 不幸的是,它没有提到什么构成I/O事件,而且无论如何,关闭可能不会被所有人视为I/O事件(我自己就是一个很好的例子)

    所以我想问的是——我能让一个套接字在关闭时发送信号或将自身插入ExceptFD中,或者以其他方式主动提示我吗

    谢谢,
    Shay

    通常,当远程对等方关闭套接字时,它会变得可读(出于
    select()
    的目的),而当您从中读取时,您会返回零字节。此零字节读取表示另一端正常关闭插座。这并不被视为例外情况。

    在我自己的应用程序中,当我的
    select()
    调用(对于读取事件)在我的文件描述符上返回时,我调用
    ioctl()
    查看缓冲区中有多少用于读取。如果有零字节,那么我用它来表示连接已关闭


    事实上,当我从这个答案开始编写linux套接字时,我发现了这一点。您还可以使用“适配器”在许多其他事件中抽象出这个事件

    比如我的一个项目

        #region Copyright
        /*
        This file came from Managed Media Aggregation, You can always find the latest version @ https://net7mma.codeplex.com/      
     */
    #endregion
    
    namespace Media.Sockets
    {
        #region NetworkConnection
    
        /// <summary>
        /// Represents a <see cref="Connection"/> specific to the Network.
        /// </summary>
        public class NetworkConnection : Connection, Common.ISocketReference
        {
            #region NetworkConnectionState
    
            [System.Flags]
            protected enum NetworkConnectionState : long
            {
                None = 0,
                Initialized = 1,
                Bound = 2,
                Connected = 4,
            }
    
            #endregion
    
            #region Fields
    
            /// <summary>
            /// Created in <see cref="CreateWaitHandle"/>, Disposed in <see cref="Dispose"/>.
            /// </summary>
            Common.Extensions.WaitHandle.DisposableWaitHandle WaitHandle;
    
            /// <summary>
            /// The date and time when the Connection was started.
            /// </summary>
            protected System.DateTime LasRemoteConnectionStartedDateTime;
    
            /// <summary>
            /// The date and time when the Connection was started.
            /// </summary>
            protected System.DateTime LastRemoteConnectionCompletedDateTime;
    
            #endregion
    
            #region Properties
    
            /// <summary>
            /// Gets the amount of time taken to connect to the <see cref="RemoteEndPoint"/>
            /// </summary>
            public System.TimeSpan RemoteConnectionTime { get { return LastRemoteConnectionCompletedDateTime - LasRemoteConnectionStartedDateTime; } }
    
            /// <summary>
            /// The <see cref="System.Net.NetworkInformation.NetworkInterface"/> assoicated with the NetworkConnection.
            /// </summary>
            public System.Net.NetworkInformation.NetworkInterface NetworkInterface { get; protected set; }
    
            /// <summary>
            /// The <see cref="System.Net.Sockets.Socket"/> assoicated with the NetworkConnection.
            /// </summary>
            public System.Net.Sockets.Socket ConnectionSocket { get; protected set; }
    
            /// <summary>
            /// Indicates if the NetworkConnection has a <see cref="NetworkInterface"/> which is not null.
            /// </summary>
            public bool HasNetworkInterface { get { return NetworkInterface != null; } }
    
            /// <summary>
            /// The <see cref="System.Net.EndPoint"/> from which this NetworkConnection connects to the <see cref="RemoteEndPoint"/>
            /// </summary>
            public System.Net.EndPoint LocalEndPoint { get; protected set; }
    
            /// <summary>
            /// Indicates if this NetworkConnection has a <see cref="LocalEndPoint"/> which is not null.
            /// </summary>
            public bool HasLocalEndPoint { get { return LocalEndPoint != null; } }
    
            /// <summary>
            /// The <see cref="System.Net.EndPoint"/> from which this NetworkConnection is connected to via the <see cref="LocalEndPoint"/>
            /// </summary>
            public System.Net.EndPoint RemoteEndPoint { get; protected set; }
    
            /// <summary>
            /// Indicates if this NetworkConnection has a <see cref="RemoteEndPoint"/> which is not null.
            /// </summary>
            public bool HasRemoteEndPoint { get { return RemoteEndPoint != null; } }
    
            /// <summary>
            /// Indicates the <see cref="NetworkConnectionState"/> assoicated with this NetworkConnection
            /// </summary>
            protected NetworkConnectionState NetworkConnectionFlags
            {
                get { return (NetworkConnectionState)Flags; }
                set { Flags = (long)value; }
            }
    
            #endregion
    
            #region Constructor
    
            public NetworkConnection()
                : base() { }
    
            public NetworkConnection(string name, bool shouldDispose)
                : base(name, shouldDispose) { }
    
            public NetworkConnection(System.Net.Sockets.Socket existingSocket, bool ownsHandle, bool shouldDispose)
                : this("System.Net.Socket-" + ownsHandle.ToString(), shouldDispose)
            {
                if (existingSocket == null) throw new System.ArgumentNullException("existingSocket");
    
                //Assign the ConnectionSocket
                ConnectionSocket = existingSocket;
    
                //Flag Initialized.
                FlagInitialized();
    
                //Assign the NetworkInterface
                NetworkInterface = Common.Extensions.NetworkInterface.NetworkInterfaceExtensions.GetNetworkInterface(ConnectionSocket);
    
                //Create a WaitHandle 
                CreateWaitHandle(ConnectionSocket.Handle, ownsHandle);
    
                //Check IsBound
                if (ConnectionSocket.IsBound)
                {
                    //Flag Bound.
                    FlagBound();
    
                    //Serialize and Assign LocalEndPoint
                    LocalEndPoint = existingSocket.LocalEndPoint;
                }
    
                //Check Connected
                if (ConnectionSocket.Connected)
                {
                    //Sample the clock
                    LasRemoteConnectionStartedDateTime = System.DateTime.UtcNow;
    
                    //Serialize and Assign RemoteEndPoint
                    RemoteEndPoint = existingSocket.RemoteEndPoint;
    
                    //Call Connect to FlagConnected and call base logic.
                    Connect();
    
                    //Sample the clock
                    LastRemoteConnectionCompletedDateTime = System.DateTime.UtcNow;
                }
            }
    
            #endregion
    
            #region NetworkChange Event Handlers
    
            void NetworkChange_NetworkAvailabilityChanged(object sender, System.Net.NetworkInformation.NetworkAvailabilityEventArgs e)
            {
                Refresh();
            }
    
            void NetworkChange_NetworkAddressChanged(object sender, System.EventArgs e)
            {
                Refresh();
            }
    
            #endregion
    
            #region Bound
    
            protected void FlagBound()
            {
                //Indicate Bound
                Flags |= (long)NetworkConnectionState.Bound;
            }
    
            protected void UnFlagBound()
            {
                //Indicate not Bound
                Flags &= (long)NetworkConnectionState.Bound;
            }
    
            #endregion
    
            #region Initialize
    
            protected void FlagInitialized()
            {
                //Indicate Connected
                Flags |= (long)NetworkConnectionState.Initialized;
            }
    
            protected void UnFlagInitialized()
            {
                //Indicate Not Connected
                Flags &= (long)NetworkConnectionState.Initialized;
            }
    
            public virtual void Initialize(bool registerForEvents)
            {
                //Check not already Initialized.
                if (false == NetworkConnectionFlags.HasFlag(NetworkConnectionState.Initialized))
                {
                    //Indicate Initialized
                    FlagInitialized();
    
                    if (registerForEvents)
                    {
                        //Attach events
                        System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;
    
                        System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
                    }
                }
            }
    
            #endregion
    
            #region Refresh
    
            public override void Refresh()
            {
                base.Refresh();
            }
    
            #endregion
    
            #region CreateConnectionSocket
    
            public void CreateConnectionSocket(System.Net.Sockets.AddressFamily addressFamily, System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType)
            {
                if (ConnectionSocket == null)
                {
                    ConnectionSocket = new System.Net.Sockets.Socket(addressFamily, socketType, protocolType);
    
                    CreateWaitHandle(ConnectionSocket.Handle, true);
                }
            }
    
            #endregion
    
            #region CreateWaitHandle
    
            public void CreateWaitHandle(System.IntPtr handle, bool ownsHandle)
            {
                if (WaitHandle == null)
                {
                    WaitHandle = new Common.Extensions.WaitHandle.DisposableWaitHandle(handle, ownsHandle);
                }
            }
    
            #endregion
    
            #region Connect
    
            protected void FlagConnected()
            {
                //Indicate Connected
                Flags |= (long)NetworkConnectionState.Connected;
            }
    
            protected void UnFlagConnected()
            {
                //Indicate Not Connected
                Flags &= (long)NetworkConnectionState.Connected;
            }
    
            public override void Connect()
            {
                //Check not already Connected.
                if (false == NetworkConnectionFlags.HasFlag(NetworkConnectionState.Connected))
                {
                    //Check IsEstablished
                    if (IsEstablished) return;
    
                    if (NetworkInterface == null) throw new System.InvalidOperationException("NetworkInterface must be assigned before calling Connect.");
    
                    if (LocalEndPoint == null) throw new System.InvalidOperationException("LocalEndPoint must be assigned before calling Connect.");
    
                    if (RemoteEndPoint == null) throw new System.InvalidOperationException("RemoteEndPoint must be assigned before calling Connect.");
    
                    //Set established
                    base.Connect();
    
                    //Indicate Connected
                    FlagConnected();
    
                    //Refresh the connection
                    Refresh();
                }
            }
    
            /// <summary>
            /// Creates the <see cref="CreateConnectionSocket"/> using the specified options and connects the socket.
            /// Assigns <see cref="LocalEndPoint"/> and <see cref="RemoteEndPoint"/>
            /// </summary>
            /// <param name="addressFamily"></param>
            /// <param name="socketType"></param>
            /// <param name="protocolType"></param>
            /// <param name="addressList"></param>
            /// <param name="port"></param>
            public virtual void Connect(System.Net.Sockets.AddressFamily addressFamily, System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType, System.Net.IPAddress[] addressList, int port)
            {
                try
                {
                    //Create the socket
                    CreateConnectionSocket(addressFamily, socketType, protocolType);
    
                    //Sample the clock
                    LasRemoteConnectionStartedDateTime = System.DateTime.UtcNow;
    
                    //Connect the socket
                    ConnectionSocket.Connect(addressList, port);
    
                    //Sample the clock
                    LastRemoteConnectionCompletedDateTime = System.DateTime.UtcNow;
                }
                finally
                {
                    //Assign the NetworkInterface
                    NetworkInterface = Common.Extensions.NetworkInterface.NetworkInterfaceExtensions.GetNetworkInterface(ConnectionSocket);
    
                    //Assign the LocalEndPoint
                    LocalEndPoint = (System.Net.IPEndPoint)ConnectionSocket.LocalEndPoint;
    
                    //Assign the RemoteEndPoint
                    RemoteEndPoint = (System.Net.IPEndPoint)ConnectionSocket.RemoteEndPoint;
    
                    //Call Connect to FlagConnected and call base logic.
                    Connect();
                }
            }
    
            #endregion
    
            #region Disconnect
    
            public virtual void Disconnect(bool allowReuse = false)
            {
                //Check not already Connected.
                if (((NetworkConnectionState)Flags).HasFlag(NetworkConnectionState.Connected))
                {
                    ConnectionSocket.Disconnect(allowReuse);
    
                    base.Disconnect();
    
                    UnFlagConnected();
    
                    Refresh();
                }
            }
    
            public override void Disconnect()
            {
                Disconnect(false);
            }
    
            #endregion
    
            #region Dispose
    
            protected override void Dispose(bool disposing)
            {
                base.Dispose(disposing);
    
                using (WaitHandle)
                {
                    System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged -= NetworkChange_NetworkAddressChanged;
    
                    System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged -= NetworkChange_NetworkAvailabilityChanged;
    
                    ConnectionSocket = null;
    
                    LocalEndPoint = RemoteEndPoint = null;
    
                    NetworkInterface = null;
                }
            }
    
            #endregion
    
            System.Collections.Generic.IEnumerable<System.Net.Sockets.Socket> Common.ISocketReference.GetReferencedSockets()
            {
                yield return ConnectionSocket;
            }
        }
    
        #endregion
    }
    
    #地区版权
    /*
    此文件来自托管媒体聚合,您始终可以找到最新版本@https://net7mma.codeplex.com/      
    */
    #端区
    名称空间媒体.Sockets
    {
    #区域网络连接
    /// 
    ///表示特定于网络的。
    /// 
    公共类网络连接:连接,Common.ISocketReference
    {
    #区域网络连接状态
    [系统标志]
    受保护的枚举网络连接状态:长
    {
    无=0,
    初始化=1,
    束缚=2,
    已连接=4,
    }
    #端区
    #区域字段
    /// 
    ///创建于,处置于。
    /// 
    Common.Extensions.WaitHandle.DisposableWaitHandle WaitHandle;
    /// 
    ///连接启动的日期和时间。
    /// 
    受保护的System.DateTime LasRemoteConnectionStartedDateTime;
    /// 
    ///连接启动的日期和时间。
    /// 
    受保护的System.DateTime LastRemoteConnectionCompletedDateTime;
    #端区
    #区域属性
    /// 
    ///获取连接到服务器所用的时间量
    /// 
    public System.TimeSpan RemoteConnectionTime{get{return LastRemoteConnectionCompletedDateTime-LasRemoteConnectionStartedDateTime;}}
    /// 
    ///已与网络连接关联。
    /// 
    public System.Net.NetworkInformation.NetworkInterface网络接口{get;protected set;}
    /// 
    ///已与网络连接关联。
    /// 
    public System.Net.Sockets.Socket连接Socket{get;protected set;}
    /// 
    ///指示NetworkConnection是否具有非null的。
    /// 
    public bool HasNetworkInterface{get{return NetworkInterface!=null;}}
    /// 
    ///此网络连接从中连接到的
    /// 
    public System.Net.EndPoint LocalEndPoint{get;protected set;}
    /// 
    ///指示此网络连接是否具有非null的。
    /// 
    public bool HasLocalEndPoint{get{return LocalEndPoint!=null;}}
    /// 
    ///通过从中连接此网络连接的
    /// 
    public System.Net.EndPoint RemoteEndPoint{get;protected set;}
    /// 
    ///指示此网络连接是否具有非null的。
    /// 
    public bool HasRemoteEndPoint{get{return RemoteEndPoint!=null;}}
    /// 
    ///指示与此网络连接关联的
    /// 
    受保护的网络连接状态网络连接标志
    {
    获取{return(NetworkConnectionState)标志;}
    设置{Flags=(长)值;}
    }
    #端区
    #区域构造函数
    公共网络连接()
    :base(){}
    公用网络连接(字符串名称,bool shouldDispose)
    :base(name,shouldDispose){}
    公用网络连接(System.Net.Sockets.Socket existingSocket,bool ownsHandle,bool shouldDispose)
    :this(“System.Net.Socket-”+ownsHandle.ToString(),shouldDispose)
    {
    如果(existingSocket==null)抛出新的System.ArgumentNullException(“existingSocket”);
    //分配ConnectionSocket
    连接插座=现有插座;
    //标志已初始化。
    FlagInitialized();
    //分配网络接口
    NetworkInterface=Common.Extensions.NetworkInterface.NetworkInterfaceExtensions.GetNetw
    
    #region Copyright
    /*
    This file came from Managed Media Aggregation, You can always find the latest version @ https://net7mma.codeplex.com/
    
     Julius.Friedman@gmail.com / (SR. Software Engineer ASTI Transportation Inc. http://www.asti-trans.com)   
     * v//
     */
    #endregion
    
    
    namespace Media.Sockets
    {
        #region Connection
    
        /// <summary>
        /// Provides a base class to facilitate the concept of a Connection.
        /// </summary>
        public abstract class Connection : Common.BaseDisposable
        {
            #region Statics
    
            /// <summary>
            /// A string with the format of:
            ///     `TypeName Id Flags Name`
            /// </summary>
            const string FormatString = "{0} {1} ({2}) {3}";
    
            #endregion
    
            #region Properties
    
            /// <summary>
            /// The unique identifier assoicated with this instance.
            /// </summary>
            public readonly System.Guid Id = System.Guid.NewGuid();
    
            /// <summary>
            /// The date and time the instance was created.
            /// </summary>
            public readonly System.DateTime Created = System.DateTime.UtcNow;
    
            /// <summary>
            /// The name assigned to this instance.
            /// </summary>
            public readonly string Name;
    
            /// <summary>
            /// Indicates if <see cref="Disconnect"/> will be called when disposing.
            /// </summary>
            public bool IsPersistent
            {
                get
                {
                    return ShouldDispose == false;
                }
                set
                {
                    ShouldDispose = value == false;
                }
            }
    
            /// <summary>
            /// Provided for derived implementations
            /// </summary>
            protected long Flags { get; set; }
    
            /// <summary>
            /// Indicates if the Connection is established.
            /// </summary>
            public virtual bool IsEstablished { get; protected set; }
    
            /// <summary>
            /// The date and time the Connection was established.
            /// </summary>
            public System.DateTime EstablishedDateTime { get; protected set; }
    
            /// <summary>
            /// The amount of time the connection has been established.
            /// </summary>
            public System.TimeSpan TimeEstablished { get { return IsEstablished ? System.DateTime.UtcNow - EstablishedDateTime : System.TimeSpan.Zero; } }
    
            #endregion
    
            #region Connect
    
            /// <summary>
            /// If <see cref="IsDisposed"/> is false, Sets <see cref="IsEstablished"/> to true.
            /// </summary>
            public virtual void Connect()
            {
                if (IsDisposed) return;
    
                EstablishedDateTime = System.DateTime.UtcNow;
    
                IsEstablished = true;
            }
    
            #endregion
    
            #region Disconnect
    
            /// <summary>
            /// If <see cref="IsDisposed"/> is false, Sets <see cref="IsEstablished"/> to false.
            /// </summary>
            public virtual void Disconnect()
            {
                if (IsDisposed) return;
    
                IsEstablished = false;
            }
    
            #endregion
    
            #region Refresh
    
            /// <summary>
            /// Refreshes the details of the Connection.
            /// Throws a <see cref="System.ObjectDisposedException"/> if <see cref="IsDisposed"/> is true.
            /// </summary>
            public virtual void Refresh()
            {
                CheckDisposed();
            }
    
            #endregion
    
            #region Dispose
    
            /// <summary>
            /// If <see cref="IsDisposed"/> is True the call returns immediately.
            /// Calls <see cref="Disconnect"/> if <see cref="IsPersistent"/> is False and calls <see cref="Common.BaseDisposable.Dispose"/>
            /// </summary>
            public override void Dispose()
            {
                if (IsDisposed) return;
    
                if (false == IsPersistent) Disconnect();
    
                base.Dispose();
            }
    
            #endregion
    
            #region Constructor
    
            public Connection(string name, bool shouldDispose)
                : base(shouldDispose)
            {
                Name = name;
            }
    
            public Connection()
                : this(string.Empty, true) { }
    
            #endregion
    
            #region ToString
    
            public override string ToString()
            {
                return string.Format(FormatString, GetType().Name.ToString(), Id.ToString(), Flags, Name);
            }
    
            #endregion
    
        }
    
        #endregion
    }
    
    #region Copyright
    /*
    This file came from Managed Media Aggregation, You can always find the latest version @ https://net7mma.codeplex.com/      
     * v//
     */
    #endregion
    
    namespace Media.Sockets
    {
    #region IPNetworkConnection
    
    /// <summary>
    /// Represents a <see cref="NetworkConnection"/> which utilizes the IP Protocol.
    /// </summary>
    public class IPNetworkConnection : NetworkConnection
    {
        #region Statics
    
        public static System.Net.NetworkInformation.IPGlobalProperties IPGlobalProperties
        {
            get { return System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties(); }
        }
    
        #region CreateIPHostEntry
    
        public static System.Net.IPHostEntry CreateIPHostEntry(System.Net.IPAddress address, string hostName, params string[] aliases)
        {
            return CreateIPHostEntry(Common.Extensions.Object.ObjectExtensions.ToArray<System.Net.IPAddress>(address),
                hostName,
                aliases);
        }
    
        public static System.Net.IPHostEntry CreateIPHostEntry(string hostName, params System.Net.IPAddress[] address)
        {
            return CreateIPHostEntry(address, hostName, null);
        }
    
        public static System.Net.IPHostEntry CreateIPHostEntry(System.Net.IPAddress[] addresses, string hostName, params string[] aliases)
        {
            return new System.Net.IPHostEntry()
            {
                AddressList = Common.Extensions.Array.ArrayExtensions.IsNullOrEmpty(addresses) ? Common.Extensions.Object.ObjectExtensions.ToArray<System.Net.IPAddress>(System.Net.IPAddress.None) : addresses,
                Aliases = Common.Extensions.Array.ArrayExtensions.IsNullOrEmpty(aliases) ? Common.Extensions.Object.ObjectExtensions.ToArray<string>(string.Empty) : aliases,
                HostName = hostName ?? string.Empty
            };
        }
    
        #endregion
    
        #endregion
    
        #region Properties
    
        /// <summary>
        /// Gets the <see cref="System.Net.NetworkInformation.IPInterfaceProperties"/> assoicated with the <see cref="NetworkInterface"/>
        /// </summary>
        public System.Net.NetworkInformation.IPInterfaceProperties IPInterfaceProperties
        {
            get { return HasNetworkInterface ? NetworkInterface.GetIPProperties() : null; }
        }
    
        /// <summary>
        /// Indicates if the <see cref="RemoteIPEndPoint"/> has a <see cref="System.Net.NetworkInformation.NetworkInterface"/> on this computer.
        /// </summary>
        public bool IsLocalConnection { get { return HasRemoteIPEndPoint && Common.Extensions.NetworkInterface.NetworkInterfaceExtensions.GetNetworkInterface(RemoteIPEndPoint) != null; } }
    
        /// <summary>
        /// Indicates if the <see cref="RemoteIPEndPoint"/> is from within the same network as this computer.
        /// </summary>
        public bool IsIntranetConnection
        {
            get { return false == IsLocalConnection && Common.Extensions.IPAddress.IPAddressExtensions.IsOnIntranet(RemoteIPEndPoint.Address); }
        }
    
        #region Local        
    
        /// <summary>
        /// The <see cref="System.Net.IPHostEntry"/> assoicated with the <see cref="LocalIPEndPoint"/>
        /// </summary>
        public System.Net.IPHostEntry LocalIPHostEntry { get; protected set; }
    
        /// <summary>
        /// Indicates if the <see cref="LocalIPHostEntry"/> is not null.
        /// </summary>
        public bool HasLocalIPHostEntry { get { return LocalIPHostEntry != null; } }
    
        /// <summary>
        /// Gets or sets the <see cref="LocalEndPoint"/>.
        /// 
        /// If the <see cref="LocalEndPoint"/> is not a <see cref="System.Net.IPEndPoint"/> a <see cref="System.InvalidOperationException"/> will be thrown.
        /// </summary>
        public System.Net.IPEndPoint LocalIPEndPoint
        {
            get { return (System.Net.IPEndPoint)LocalEndPoint; }
            set
            {
                if (false == LocalEndPoint is System.Net.IPEndPoint) throw new System.InvalidOperationException("LocalEndPoint is not a System.Net.IPEndPoint");
    
                LocalEndPoint = value;
            }
        }
    
        /// <summary>
        /// Indicates if the <see cref="LocalIPEndPoint"/> is not null.
        /// </summary>
        public bool HasLocalIPEndPoint { get { return LocalIPEndPoint != null; } }
    
        #endregion
    
        #region Dhcp
    
        /// <summary>
        /// Gets the <see cref="System.Net.NetworkInformation.IPAddressCollection"/> assoicated with the <see cref="IPInterfaceProperties"/>
        /// </summary>
        public virtual System.Net.NetworkInformation.IPAddressCollection DhcpServerAddresses
        {
            get
            {
                return IPInterfaceProperties.DhcpServerAddresses;
            }
        }
    
        /// <summary>
        /// Indicates if the IPNetworkConnection utilized Dhcp
        /// </summary>
        public bool UsesDhcp
        {
            get
            {
                return DhcpServerAddresses.Count > 0; /* && DhcpLeaseLifetime != System.TimeSpan.MinValue;*/
            }
        }
    
        //Could make a Superset class of to unify paths..
        //System.Net.NetworkInformation.IPAddressInformationCollection ipAddressCollection;
    
        /// <summary>
        /// If <see cref="UsesDhcp"/> the amount of time of the IPAddress is leased according the <see cref="System.Net.NetworkInformation.IPAddressInformation"/> assoicated with the <see cref="LocalIPEndPoint"/>.
        /// 
        /// If the <see cref="LocalIPEndPoint"/> is not found in the leased <see cref="System.Net.NetworkInformation.IPAddressInformation"/> then <see cref="Common.Extensions.TimeSpan.TimeSpanExtensions.InfiniteTimeSpan"/> is returned.
        /// </summary>
        public System.TimeSpan DhcpLeaseLifetime
        {
            get
            {
                //If there is no Dhcp server the DhcpLeaveLifeTime is 0
                if (false == UsesDhcp) return System.TimeSpan.Zero;
    
                //Check Multicast if the address IsMulticast
                if (Common.Extensions.IPAddress.IPAddressExtensions.IsMulticast(LocalIPEndPoint.Address))
                {
                    System.Net.NetworkInformation.MulticastIPAddressInformationCollection multicastIPAddressInformationCollection = IPInterfaceProperties.MulticastAddresses;
    
                    foreach (System.Net.NetworkInformation.MulticastIPAddressInformation multicastIPAddressInformation in multicastIPAddressInformationCollection)
                    {
                        if (multicastIPAddressInformation.Address.Equals(LocalIPEndPoint.Address))
                        {
                            return System.TimeSpan.FromSeconds(multicastIPAddressInformation.DhcpLeaseLifetime);
                        }
                    }
                }
                else //Check Unicast otherwise
                {
                    System.Net.NetworkInformation.UnicastIPAddressInformationCollection unicastIPAddressInformationCollection = IPInterfaceProperties.UnicastAddresses;
    
                    foreach (System.Net.NetworkInformation.UnicastIPAddressInformation unicastIPAddressInformation in unicastIPAddressInformationCollection)
                    {
                        if (unicastIPAddressInformation.Address.Equals(LocalIPEndPoint.Address))
                        {
                            return System.TimeSpan.FromSeconds(unicastIPAddressInformation.DhcpLeaseLifetime);
                        }
                    }
                }
    
                //Could not find a an IPAddress which matched the LocalIPEndPoint, indicate infinite timeout.
                return Common.Extensions.TimeSpan.TimeSpanExtensions.InfiniteTimeSpan;
            }
        }
    
        /// <summary>
        /// If <see cref="UsesDhcp"/> Gets the number of seconds remaining during which this address is valid.
        /// 
        /// If the <see cref="LocalIPEndPoint"/> is not found in the leased <see cref="System.Net.NetworkInformation.IPAddressInformation"/> then <see cref="Common.Extensions.TimeSpan.TimeSpanExtensions.InfiniteTimeSpan"/> is returned.
        /// </summary>
        public System.TimeSpan DhcpAddressValidLifetime
        {
            get
            {
                //If there is no Dhcp server the DhcpLeaveLifeTime is 0
                if (false == UsesDhcp) return System.TimeSpan.Zero;
    
                //Check Multicast if the address IsMulticast
                if (Common.Extensions.IPAddress.IPAddressExtensions.IsMulticast(LocalIPEndPoint.Address))
                {
                    System.Net.NetworkInformation.MulticastIPAddressInformationCollection multicastIPAddressInformationCollection = IPInterfaceProperties.MulticastAddresses;
    
                    foreach (System.Net.NetworkInformation.MulticastIPAddressInformation multicastIPAddressInformation in multicastIPAddressInformationCollection)
                    {
                        if (multicastIPAddressInformation.Address.Equals(LocalIPEndPoint.Address))
                        {
                            return System.TimeSpan.FromSeconds(multicastIPAddressInformation.AddressValidLifetime);
                        }
                    }
                }
                else //Check Unicast otherwise
                {
                    System.Net.NetworkInformation.UnicastIPAddressInformationCollection unicastIPAddressInformationCollection = IPInterfaceProperties.UnicastAddresses;
    
                    foreach (System.Net.NetworkInformation.UnicastIPAddressInformation unicastIPAddressInformation in unicastIPAddressInformationCollection)
                    {
                        if (unicastIPAddressInformation.Address.Equals(LocalIPEndPoint.Address))
                        {
                            return System.TimeSpan.FromSeconds(unicastIPAddressInformation.AddressValidLifetime);
                        }
                    }
                }
    
                //Could not find a an IPAddress which matched the LocalIPEndPoint, indicate infinite timeout.
                return Common.Extensions.TimeSpan.TimeSpanExtensions.InfiniteTimeSpan;
            }
        }
    
        /// <summary>
        /// If <see cref="UsesDhcp"/> Gets the number of seconds remaining during which this address is the preferred address.
        /// 
        /// If the <see cref="LocalIPEndPoint"/> is not found in the leased <see cref="System.Net.NetworkInformation.IPAddressInformation"/> then <see cref="Common.Extensions.TimeSpan.TimeSpanExtensions.InfiniteTimeSpan"/> is returned.
        /// </summary>
        public System.TimeSpan DhcpAddressPreferredLifetime
        {
            get
            {
                //If there is no Dhcp server the DhcpLeaveLifeTime is 0
                if (false == UsesDhcp) return System.TimeSpan.Zero;
    
                //Check Multicast if the address IsMulticast
                if (Common.Extensions.IPAddress.IPAddressExtensions.IsMulticast(LocalIPEndPoint.Address))
                {
                    System.Net.NetworkInformation.MulticastIPAddressInformationCollection multicastIPAddressInformationCollection = IPInterfaceProperties.MulticastAddresses;
    
                    foreach (System.Net.NetworkInformation.MulticastIPAddressInformation multicastIPAddressInformation in multicastIPAddressInformationCollection)
                    {
                        if (multicastIPAddressInformation.Address.Equals(LocalIPEndPoint.Address))
                        {
                            return System.TimeSpan.FromSeconds(multicastIPAddressInformation.AddressPreferredLifetime);
                        }
                    }
                }
                else //Check Unicast otherwise
                {
                    System.Net.NetworkInformation.UnicastIPAddressInformationCollection unicastIPAddressInformationCollection = IPInterfaceProperties.UnicastAddresses;
    
                    foreach (System.Net.NetworkInformation.UnicastIPAddressInformation unicastIPAddressInformation in unicastIPAddressInformationCollection)
                    {
                        if (unicastIPAddressInformation.Address.Equals(LocalIPEndPoint.Address))
                        {
                            return System.TimeSpan.FromSeconds(unicastIPAddressInformation.AddressPreferredLifetime);
                        }
                    }
                }
    
                //Could not find a an IPAddress which matched the LocalIPEndPoint, indicate infinite timeout.
                return Common.Extensions.TimeSpan.TimeSpanExtensions.InfiniteTimeSpan;
            }
        }
    
        #endregion
    
        #region Remote
    
        /// <summary>
        /// Provides information about the <see cref="RemoteEndPoint"/>.Address
        /// </summary>
        public System.Net.NetworkInformation.IPAddressInformation RemoteAddressInformation { get; protected set; }
    
        /// <summary>
        /// Indicates if the <see cref="RemoteAddressInformation"/> is not null.
        /// </summary>
        public bool HasRemoteAddressInformation { get { return RemoteAddressInformation != null; } }
    
        /// <summary>
        /// The <see cref="System.Net.IPHostEntry"/> assoicated with the <see cref="RemoteIPEndPoint"/>
        /// </summary>
        public System.Net.IPHostEntry RemoteIPHostEntry { get; protected set; }
    
        /// <summary>
        /// Indicates if the <see cref="RemoteIPHostEntry"/> is not null.
        /// </summary>
        public bool HasRemoteIPHostEntry { get { return RemoteIPHostEntry != null; } }
    
        /// <summary>
        /// Gets or sets the <see cref="RemoteEndPoint"/>.
        /// 
        /// If the <see cref="RemoteEndPoint"/> is not a <see cref="System.Net.IPEndPoint"/> a <see cref="System.InvalidOperationException"/> will be thrown.
        /// </summary>
        public System.Net.IPEndPoint RemoteIPEndPoint
        {
            get { return (System.Net.IPEndPoint)RemoteEndPoint; }
            set
            {
                if (false == RemoteEndPoint is System.Net.IPEndPoint) throw new System.InvalidOperationException("RemoteEndPoint is not a System.Net.IPEndPoint");
    
                RemoteEndPoint = value;
            }
        }
    
        /// <summary>
        /// Indicates if the <see cref="RemoteEndPoint"/> is a <see cref="System.Net.IPEndPoint"/>
        /// </summary>
        public bool HasRemoteIPEndPoint { get { return RemoteIPEndPoint != null; } }
    
        #endregion
    
        #endregion
    
        #region Constructor
    
        /// <summary>
        /// Creates a new NetworkConnection with the given.
        /// </summary>
        /// <param name="remoteIPHostEntry">given</param>
        public IPNetworkConnection(System.Net.IPHostEntry remoteIPHostEntry)
            : base()
        {
            if (remoteIPHostEntry == null) throw new System.ArgumentNullException("remoteIPHostEntry");
    
            RemoteIPHostEntry = remoteIPHostEntry;            
        }
    
        /// <summary>
        /// Creates a new NetworkConnection by resolving the given using <see cref="System.Net.Dns.GetHostEntry"/>
        /// </summary>
        /// <param name="hostNameOrAddress">given</param>
        public IPNetworkConnection(string hostNameOrAddress) :
            this(System.Net.Dns.GetHostEntry(hostNameOrAddress))
        {
            RemoteAddressInformation = new IPAddressInformation(System.Net.IPAddress.None, true, false);
        }
    
        /// <summary>
        /// Creates a new NetworkConnection and <see cref="new System.Net.IPHostEntry"/> using the given address.
        /// </summary>
        /// <param name="address">The address</param>
        public IPNetworkConnection(System.Net.IPAddress address) :
            this(CreateIPHostEntry(string.Empty, address))
        {
            RemoteAddressInformation = new IPAddressInformation(System.Net.IPAddress.None, false, false);
        }
    
        public IPNetworkConnection(System.Uri uri) : this(uri.DnsSafeHost) { }
    
        #endregion
    
        #region Refresh
    
        /// <summary>
        /// If <see cref="HasNetworkInterface"/> is True And <see cref="HasLocalIPEndPoint"/> then <see cref="NetworkInterface"/> is updated using <see cref="Common.Extensions.NetworkInterface.NetworkInterfaceExtensions.GetNetworkInterface"/>
        /// </summary>
        public void RefreshNetworkInterface()
        {
            if (HasNetworkInterface && HasLocalIPEndPoint)
            {                
                NetworkInterface = Common.Extensions.NetworkInterface.NetworkInterfaceExtensions.GetNetworkInterface(LocalIPEndPoint);
            }
        }
    
        /// <summary>
        /// If <see cref="HasRemoteAddressInformation"/> is True And <see cref="RemoteAddressInformation.IsDnsEligible"/> then the <see cref="RemoteIPHostEntry"/> is updated using <see cref="System.Net.Dns.GetHostEntry"/>
        /// </summary>
        public void RefreshRemoteIPHostEntry()
        {
            if (HasRemoteAddressInformation && RemoteAddressInformation.IsDnsEligible)
            {
                RemoteIPHostEntry = System.Net.Dns.GetHostEntry(RemoteIPEndPoint.Address);
            }
        }
    
        public override void Refresh()
        {
            if (IsDisposed) return;
    
            base.Refresh();
    
            RefreshNetworkInterface();
    
            RefreshRemoteIPHostEntry();
        }
    
        #endregion
    
        #region Connect
    
        public void Connect(int addressIndex, System.Net.NetworkInformation.NetworkInterface networkInterface, int port = 0)
        {
            if (ConnectionSocket == null) throw new System.InvalidOperationException("There must be a ConnectionSocket assigned before calling Connect.");
    
            if (addressIndex < 0) throw new System.IndexOutOfRangeException("addressIndex must be > 0 and < HostEntry.AddressList.Length");
    
            if (networkInterface == null) throw new System.ArgumentNullException("networkInterface");
    
            NetworkInterface = networkInterface;
    
            RemoteEndPoint = new System.Net.IPEndPoint(RemoteIPHostEntry.AddressList[addressIndex], port);
    
            Connect();
    
            LocalEndPoint = ConnectionSocket.LocalEndPoint;
    
            RemoteAddressInformation = new IPAddressInformation(RemoteIPEndPoint.Address, RemoteAddressInformation.IsDnsEligible, RemoteAddressInformation.IsTransient);
        }
    
        #endregion
    
        #region Dispose
    
        public override void Dispose()
        {
            base.Dispose();
    
            RemoteIPHostEntry = null;
    
            LocalEndPoint = RemoteEndPoint = null;
    
            NetworkInterface = null;
        }
    
        #endregion
    }
    
    #endregion
    }
    
     #region Copyright
    /*
    This file came from Managed Media Aggregation, You can always find the latest version @ https://net7mma.codeplex.com/
    
     Julius.Friedman@gmail.com / (SR. Software Engineer ASTI Transportation Inc. http://www.asti-trans.com)
    
    Permission is hereby granted, free of charge, 
     * to any person obtaining a copy of this software and associated documentation files (the "Software"), 
     * to deal in the Software without restriction, 
     * including without limitation the rights to :
     * use, 
     * copy, 
     * modify, 
     * merge, 
     * publish, 
     * distribute, 
     * sublicense, 
     * and/or sell copies of the Software, 
     * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
     * 
     * 
     * JuliusFriedman@gmail.com should be contacted for further details.
    
    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
     * 
     * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
     * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
     * TORT OR OTHERWISE, 
     * ARISING FROM, 
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     * 
     * v//
     */
    #endregion
    
    namespace Media.Sockets
    {
        #region TcpNetworkConnection
    
        public class TcpNetworkConnection : NetworkConnection
        {
            #region Statics
    
            public static System.Net.NetworkInformation.TcpConnectionInformation[] TcpConnectionInformation
            {
                get { return IPNetworkConnection.IPGlobalProperties.GetActiveTcpConnections(); }
            }
    
            #endregion
    
            public TcpNetworkConnection(string name, bool shouldDispose) : base(name, shouldDispose) { }
        }
    
        #endregion
    }
    
    #region Copyright
    /*
    This file came from Managed Media Aggregation, You can always find the latest version @ https://net7mma.codeplex.com/
    
     Julius.Friedman@gmail.com / (SR. Software Engineer ASTI Transportation Inc. http://www.asti-trans.com)
    
    Permission is hereby granted, free of charge, 
     * to any person obtaining a copy of this software and associated documentation files (the "Software"), 
     * to deal in the Software without restriction, 
     * including without limitation the rights to :
     * use, 
     * copy, 
     * modify, 
     * merge, 
     * publish, 
     * distribute, 
     * sublicense, 
     * and/or sell copies of the Software, 
     * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
     * 
     * 
     * JuliusFriedman@gmail.com should be contacted for further details.
    
    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
     * 
     * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
     * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
     * TORT OR OTHERWISE, 
     * ARISING FROM, 
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     * 
     * v//
     */
    #endregion
    
    namespace Media.Sockets
    {
        #region TcpNetworkConnection
    
        public class TcpIPNetworkConnection : IPNetworkConnection
        {
            #region Statics
    
            public static System.Net.NetworkInformation.TcpConnectionInformation[] TcpConnectionInformation
            {
                get { return IPNetworkConnection.IPGlobalProperties.GetActiveTcpConnections(); }
            }
    
            #endregion
    
            public TcpIPNetworkConnection() : base(string.Empty) { }
        }
    
        #endregion
    }