Ejemplo n.º 1
0
        internal UdpOutputChannel(UdpChannelFactory factory, EndpointAddress remoteAddress, Uri via, MessageEncoder encoder)
            : base(factory)
        {
            // validate addressing arguments
            if (!string.Equals(via.Scheme, UdpConstants.Scheme, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                                                          "The scheme {0} specified in address is not supported.", via.Scheme), "via");
            }

            if (via.IsDefaultPort)
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                                                          "The address {0} must specify a remote port.", via), "via");
            }

            // convert the Uri host into an IP Address
            IPAddress remoteIP = null;

            switch (via.HostNameType)
            {
            default:
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                                                          "Cannot determine the remote host address from {0}.",
                                                          this.via.ToString()), "via");

            case UriHostNameType.IPv4:
            case UriHostNameType.IPv6:
                remoteIP = IPAddress.Parse(via.Host);
                break;

            case UriHostNameType.Basic:
            case UriHostNameType.Dns:
            {
                IPHostEntry hostEntry = Dns.GetHostEntry(via.Host);
                if (hostEntry.AddressList.Length > 0)
                {
                    remoteIP = hostEntry.AddressList[0];
                }
                else
                {
                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                                                              "Failed to resolve remote host: {0}.", via.Host),
                                                "via");
                }
                break;
            }
            }

            if (factory.Multicast && !UdpChannelHelpers.IsInMulticastRange(remoteIP))
            {
                throw new ArgumentOutOfRangeException("remoteEndPoint", "Via must be in the valid multicast range.");
            }

            this.parent         = factory;
            this.remoteAddress  = remoteAddress;
            this.via            = via;
            this.encoder        = encoder;
            this.remoteEndPoint = new IPEndPoint(remoteIP, via.Port);
            this.socket         = new Socket(this.remoteEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            this.socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
            if (parent.SendPort != 0)
            {
                this.socket.Bind(new IPEndPoint(IPAddress.Any, parent.SendPort));
            }
            //if (parent.Multicast)
            //{
            //this.socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
            //this.socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(remoteIP));
            //socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 50);//貌似不需要这么设置,自动支持组播

#if LATER // Support outgoing interface
            if (this.remoteEndPoint.AddressFamily == AddressFamily.InterNetwork)
            {
                this.socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, IPAddress.HostToNetworkOrder((int)interfaceIndex));
            }
            else     //  we are IPv6
            {
                this.sendSocketV6.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastInterface, (int)interfaceIndex);
            }
#endif
            //}
        }