public override bool Equals(object obj)
        {
            ConnectionEndpoint item = obj as ConnectionEndpoint;

            if (item == null)
            {
                return(false);
            }
            return(Id().Equals(item.Id()));
        }
        private async Task DisconnectAsync(ConnectionEndpoint remoteEndPoint)
        {
            Task <Socket> existing = null;

            if (_Sockets.TryRemove(remoteEndPoint, out existing))
            {
                try
                {
                    var socket = await existing.ConfigureAwait(false);

                    socket.AsSafeDisposable().Dispose();
                }
                catch { }
            }
        }
        protected virtual async Task <Socket> CreateSocket(ConnectionEndpoint endpoint, CancellationToken cancellation)
        {
            List <IPAddress> possibleAddresses = new List <IPAddress>();
            IPAddress        address;

            if (!IPAddress.TryParse(endpoint.Host, out address))
            {
                foreach (var add in (await Dns.GetHostEntryAsync(endpoint.Host).ConfigureAwait(false)).AddressList)
                {
                    possibleAddresses.Add(add);
                }
                if (possibleAddresses.Count == 0)
                {
                    throw new SocketException(11001);                     //WSAHOST_NOT_FOUND
                }
            }
            else
            {
                possibleAddresses.Add(address);
            }

            Exception lastException = null;

            foreach (var possibleAddress in possibleAddresses)
            {
                try
                {
                    Socket s = new Socket(possibleAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                    try
                    {
                        // Windows default to true, but some linux distro does not support this
                        s.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
                    }
                    catch (SocketException) { }
                    await s.ConnectAsync(new IPEndPoint(possibleAddress, endpoint.Port), cancellation).ConfigureAwait(false);

                    return(s);
                }
                catch (Exception ex) { lastException = ex; }
            }
            ExceptionDispatchInfo.Capture(lastException).Throw();
            throw new NotImplementedException("impossible to reach");
        }