Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.ServiceModel.Discovery / System / ServiceModel / Channels / UdpChannelFactory.cs / 1484997 / UdpChannelFactory.cs
//---------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------- namespace System.ServiceModel.Channels { using System; using System.Collections.Generic; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Runtime; using System.ServiceModel.Discovery; class UdpChannelFactory : ChannelFactoryBase{ MessageEncoderFactory messageEncoderFactory; IUdpTransportSettings settings; internal UdpChannelFactory(IUdpTransportSettings settings, BindingContext context) : base(context.Binding) { Fx.Assert(settings != null, "settings can't be null"); Fx.Assert(context != null, "binding context can't be null"); this.settings = settings; if (this.settings.SocketReceiveBufferSize < this.settings.MaxReceivedMessageSize) { throw FxTrace.Exception.ArgumentOutOfRange("SocketReceiveBufferSize", this.settings.SocketReceiveBufferSize, SR.Property1LessThanOrEqualToProperty2("MaxReceivedMessageSize", this.settings.MaxReceivedMessageSize, "SocketReceiveBufferSize", this.settings.SocketReceiveBufferSize)); } this.messageEncoderFactory = UdpUtility.GetEncoder(context); this.BufferManager = BufferManager.CreateBufferManager(settings.MaxBufferPoolSize, (int)settings.MaxReceivedMessageSize); } BufferManager BufferManager { get; set; } public override T GetProperty () { T messageEncoderProperty = this.messageEncoderFactory.Encoder.GetProperty (); if (messageEncoderProperty != null) { return messageEncoderProperty; } if (typeof(T) == typeof(MessageVersion)) { return (T)(object)this.messageEncoderFactory.Encoder.MessageVersion; } return base.GetProperty (); } protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { this.OnOpen(timeout); return new CompletedAsyncResult(callback, state); } protected override IDuplexChannel 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; ClientUdpDuplexChannel channel; lock (this.ThisLock) { bool isMulticast; sockets = GetSockets(via, out remoteEndPoint, out isMulticast); EndpointAddress localAddress = new EndpointAddress(EndpointAddress.AnonymousUri); channel = new ClientUdpDuplexChannel(this, sockets, remoteEndPoint, localAddress, to, via, isMulticast); } return channel; } protected override void OnEndOpen(IAsyncResult result) { CompletedAsyncResult.End(result); } protected override void OnOpen(TimeSpan timeout) { } //will only return > 1 socket when both of the following are true: // 1) multicast // 2) sending on all interfaces UdpSocket[] GetSockets(Uri via, out IPEndPoint remoteEndPoint, out bool isMulticast) { UdpSocket[] results = null; remoteEndPoint = null; IPAddress[] remoteAddressList; isMulticast = false; UdpUtility.ThrowIfNoSocketSupport(); if (via.HostNameType == UriHostNameType.IPv6 || via.HostNameType == UriHostNameType.IPv4) { IPAddress address = IPAddress.Parse(via.DnsSafeHost); isMulticast = UdpUtility.IsMulticastAddress(address); if (isMulticast && !settings.EnableMulticast) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.UdpMulticastNotEnabled(via))); } remoteAddressList = new IPAddress[] { address }; } else { remoteAddressList = DnsCache.Resolve(via.DnsSafeHost).AddressList; } if (remoteAddressList.Length < 1) { // System.Net.Dns shouldn't ever allow this to happen, but... Fx.Assert("DnsCache returned a HostEntry with zero length address list"); throw FxTrace.Exception.AsError(new EndpointNotFoundException(SR.DnsResolveFailed(via.DnsSafeHost))); } remoteEndPoint = new IPEndPoint(remoteAddressList[0], via.Port); IPAddress localAddress; if (via.IsLoopback) { localAddress = (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Loopback : IPAddress.IPv6Loopback); } else { localAddress = (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any); } int port = 0; if (isMulticast) { List socketList = new List (); NetworkInterface[] adapters = UdpUtility.GetMulticastInterfaces(this.settings.MulticastInterfaceId); //if listening on a specific adapter, don't disable multicast loopback on that adapter. bool allowMulticastLoopback = !string.IsNullOrEmpty(this.settings.MulticastInterfaceId); for (int i = 0; i < adapters.Length; i++) { if (adapters[i].OperationalStatus == OperationalStatus.Up) { IPInterfaceProperties properties = adapters[i].GetIPProperties(); bool isLoopbackAdapter = adapters[i].NetworkInterfaceType == NetworkInterfaceType.Loopback; if (isLoopbackAdapter) { socketList.Add(UdpUtility.CreateListenSocket(localAddress, ref port, this.settings.SocketReceiveBufferSize, this.settings.TimeToLive, UdpUtility.GetLoopbackInterfaceIndex(adapters[i], localAddress.AddressFamily == AddressFamily.InterNetwork), allowMulticastLoopback, isLoopbackAdapter)); } else if (localAddress.AddressFamily == AddressFamily.InterNetworkV6) { if (adapters[i].Supports(NetworkInterfaceComponent.IPv6)) { IPv6InterfaceProperties v6Properties = properties.GetIPv6Properties(); if (v6Properties != null) { socketList.Add(UdpUtility.CreateListenSocket(localAddress, ref port, this.settings.SocketReceiveBufferSize, this.settings.TimeToLive, v6Properties.Index, allowMulticastLoopback, isLoopbackAdapter)); } } } else { if (adapters[i].Supports(NetworkInterfaceComponent.IPv4)) { IPv4InterfaceProperties v4Properties = properties.GetIPv4Properties(); if (v4Properties != null) { socketList.Add(UdpUtility.CreateListenSocket(localAddress, ref port, this.settings.SocketReceiveBufferSize, this.settings.TimeToLive, v4Properties.Index, allowMulticastLoopback, isLoopbackAdapter)); } } } } //CreateListenSocket sets the port, but since we aren't listening //on multicast, each socket can't share the same port. port = 0; } if (socketList.Count == 0) { throw FxTrace.Exception.AsError(new ArgumentException(SR.UdpFailedToFindMulticastAdapter(via))); } results = socketList.ToArray(); } else { UdpSocket socket = UdpUtility.CreateUnicastListenSocket(localAddress, ref port, this.settings.SocketReceiveBufferSize, this.settings.TimeToLive); results = new UdpSocket[] { socket }; } Fx.Assert(results != null, "GetSockets(...) return results should never be null. An exception should have been thrown but wasn't."); return results; } sealed class ClientUdpDuplexChannel : UdpDuplexChannel { EndpointAddress to; ChannelParameterCollection channelParameters; internal ClientUdpDuplexChannel(UdpChannelFactory factory, UdpSocket[] sockets, IPEndPoint remoteEndPoint, EndpointAddress localAddress, EndpointAddress to, Uri via, bool isMulticast) : base(factory, factory.messageEncoderFactory.Encoder, factory.BufferManager, sockets, factory.settings.RetransmissionSettings, factory.settings.MaxPendingMessageCount, localAddress, via, isMulticast, (int)factory.settings.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.settings.DuplicateMessageHistoryLength > 0) { this.DuplicateDetector = new DuplicateMessageDetector(factory.settings.DuplicateMessageHistoryLength); } else { this.DuplicateDetector = null; } } protected override bool IgnoreSerializationException { get { return this.IsMulticast; } } public override EndpointAddress RemoteAddress { get { return this.to; } } public IPEndPoint RemoteEndPoint { get; private set; } public override T GetProperty () { if (typeof(T) == typeof(ChannelParameterCollection)) { if (this.State == CommunicationState.Created) { lock (ThisLock) { if (this.channelParameters == null) { this.channelParameters = new ChannelParameterCollection(); } } } return (T)(object)this.channelParameters; } else { return base.GetProperty (); } } protected override UdpSocket[] GetSendSockets(Message message, out IPEndPoint remoteEndPoint, out Exception exceptionToBeThrown) { UdpSocket[] socketList = null; remoteEndPoint = this.RemoteEndPoint; exceptionToBeThrown = null; if (this.IsMulticast) { //always send on all sockets... socketList = this.Sockets; } else { Fx.Assert(this.Sockets.Length == 1, "Unicast Send socket list on client should always be 1 item long"); socketList = this.Sockets; } return socketList; } protected override void OnOpened() { this.ReceiveManager = new UdpSocketReceiveManager(this.Sockets, UdpConstants.PendingReceiveCountPerProcessor * Environment.ProcessorCount, base.BufferManager, this); //do the state change to CommunicationState.Opened before starting the receive loop. //this avoids a ---- between transitioning state and processing messages that are //already in the socket receive buffer. base.OnOpened(); this.ReceiveManager.Open(); } protected override void AddHeadersTo(Message message) { Fx.Assert(message != null, "Message can't be null"); if (message.Version.Addressing != AddressingVersion.None) { this.to.ApplyTo(message); } message.Properties.Via = this.Via; base.AddHeadersTo(message); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HttpCapabilitiesBase.cs
- MenuItem.cs
- RemotingHelper.cs
- WindowPattern.cs
- JsonFormatGeneratorStatics.cs
- ContextStack.cs
- ListDictionary.cs
- EventDescriptorCollection.cs
- HostVisual.cs
- ThrowOnMultipleAssignment.cs
- AnnotationObservableCollection.cs
- BrowserDefinitionCollection.cs
- Codec.cs
- Highlights.cs
- KeyedHashAlgorithm.cs
- FrameworkElementFactory.cs
- WebPartTransformerCollection.cs
- SiteIdentityPermission.cs
- IndexingContentUnit.cs
- ColorInterpolationModeValidation.cs
- NamedPermissionSet.cs
- rsa.cs
- DataBoundLiteralControl.cs
- CompressedStack.cs
- ExpressionBinding.cs
- Stack.cs
- BaseDataBoundControlDesigner.cs
- SystemInformation.cs
- QueryProcessor.cs
- ResourceExpressionBuilder.cs
- EnvelopedPkcs7.cs
- APCustomTypeDescriptor.cs
- ParallelTimeline.cs
- GeneralTransformCollection.cs
- WinFormsSecurity.cs
- SynchronizingStream.cs
- MultiView.cs
- Soap.cs
- DetailsViewRowCollection.cs
- DesignTimeType.cs
- SymbolPair.cs
- GroupBoxAutomationPeer.cs
- BamlRecordReader.cs
- CancelEventArgs.cs
- BCLDebug.cs
- CounterSetInstance.cs
- EventLogStatus.cs
- CodeThrowExceptionStatement.cs
- CollectionEditVerbManager.cs
- SubstitutionDesigner.cs
- DLinqColumnProvider.cs
- DataBoundControlHelper.cs
- SqlProcedureAttribute.cs
- CharEntityEncoderFallback.cs
- ContractInferenceHelper.cs
- HMACSHA512.cs
- PackagePart.cs
- KerberosSecurityTokenAuthenticator.cs
- WorkflowApplicationTerminatedException.cs
- DependencyPropertyAttribute.cs
- StyleSheetComponentEditor.cs
- DetailsViewModeEventArgs.cs
- TemplateXamlParser.cs
- StringResourceManager.cs
- latinshape.cs
- _ListenerRequestStream.cs
- GcHandle.cs
- WindowsTitleBar.cs
- XLinq.cs
- CodeIdentifiers.cs
- Misc.cs
- LayoutUtils.cs
- CacheAxisQuery.cs
- NamespaceQuery.cs
- ProtocolsConfigurationHandler.cs
- Random.cs
- InputLanguageManager.cs
- VariantWrapper.cs
- HashCryptoHandle.cs
- Parser.cs
- XmlAttributeOverrides.cs
- PeerNeighborManager.cs
- CodePageUtils.cs
- NodeFunctions.cs
- Light.cs
- EventDescriptor.cs
- DateTimeFormat.cs
- HttpHandlerAction.cs
- RoleServiceManager.cs
- EditorPart.cs
- TimeZone.cs
- Util.cs
- ModelTreeEnumerator.cs
- XmlWriterTraceListener.cs
- Pointer.cs
- SQLMembershipProvider.cs
- ComplexType.cs
- ConnectionStringsSection.cs
- PictureBoxDesigner.cs
- GroupBox.cs