internal ClientUdpDuplexChannel(UdpChannelFactory <IDuplexChannel> factory, UdpSocket[] sockets, IPEndPoint remoteEndPoint, EndpointAddress localAddress, EndpointAddress to, Uri via, bool isMulticast)
                : base(factory,
                       factory.messageEncoderFactory.Encoder,
                       factory.BufferManager,
                       sockets,
                       factory.udpTransportBindingElement.RetransmissionSettings,
                       factory.udpTransportBindingElement.MaxPendingMessagesTotalSize,
                       localAddress,
                       via,
                       isMulticast,
                       (int)factory.udpTransportBindingElement.MaxReceivedMessageSize)
            {
                Fx.Assert(to != null, "to address can't be null for this constructor...");
                Fx.Assert(remoteEndPoint != null, "remoteEndPoint can't be null");

                this.RemoteEndPoint = remoteEndPoint;
                this.to             = to;

                if (factory.udpTransportBindingElement.DuplicateMessageHistoryLength > 0)
                {
                    this.DuplicateDetector = new DuplicateMessageDetector(factory.udpTransportBindingElement.DuplicateMessageHistoryLength);
                }
                else
                {
                    this.DuplicateDetector = null;
                }

                UdpOutputChannel udpOutputChannel = new ClientUdpOutputChannel(factory, remoteEndPoint, factory.messageEncoderFactory.Encoder, factory.BufferManager, sockets, factory.udpTransportBindingElement.RetransmissionSettings, to, via, isMulticast);

                this.SetOutputChannel(udpOutputChannel);
            }
        protected override TChannel OnCreateChannel(EndpointAddress to, Uri via)
        {
            Fx.Assert(to != null, "To address should have been validated as non-null by ChannelFactoryBase");
            Fx.Assert(via != null, "Via address should have been validated as non-null by ChannelFactoryBase");

            if (!via.IsAbsoluteUri)
            {
                throw FxTrace.Exception.Argument("via", SR.RelativeUriNotAllowed(via));
            }

            if (!via.Scheme.Equals(UdpConstants.Scheme, StringComparison.OrdinalIgnoreCase))
            {
                throw FxTrace.Exception.Argument("via", SR.UriSchemeNotSupported(via.Scheme));
            }

            if (!UdpUtility.IsSupportedHostNameType(via.HostNameType))
            {
                throw FxTrace.Exception.Argument("via", SR.UnsupportedUriHostNameType(via.Host, via.HostNameType));
            }

            if (via.IsDefaultPort || via.Port == 0)
            {
                throw FxTrace.Exception.ArgumentOutOfRange("via", via, SR.PortNumberRequiredOnVia(via));
            }

            UdpSocket[] sockets        = null;
            IPEndPoint  remoteEndPoint = null;
            TChannel    channel;

            lock (this.ThisLock)
            {
                bool isMulticast;
                sockets = GetSockets(via, out remoteEndPoint, out isMulticast);

                EndpointAddress localAddress = new EndpointAddress(EndpointAddress.AnonymousUri);

                if (typeof(TChannel) == typeof(IDuplexChannel))
                {
                    UdpChannelFactory <IDuplexChannel> duplexChannelFactory = (UdpChannelFactory <IDuplexChannel>)(object) this;
                    channel = (TChannel)(object)new ClientUdpDuplexChannel(duplexChannelFactory, sockets, remoteEndPoint, localAddress, to, via, isMulticast);
                }
                else
                {
                    UdpChannelFactory <IOutputChannel> outputChannelFactory = (UdpChannelFactory <IOutputChannel>)(object) this;
                    channel = (TChannel)(object)new ClientUdpOutputChannel(
                        outputChannelFactory,
                        remoteEndPoint,
                        outputChannelFactory.messageEncoderFactory.Encoder,
                        this.BufferManager,
                        sockets,
                        outputChannelFactory.udpTransportBindingElement.RetransmissionSettings,
                        to,
                        via,
                        isMulticast);
                }
            }

            return(channel);
        }