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
- SystemFonts.cs
- _ConnectionGroup.cs
- RequestCacheValidator.cs
- EnumerableCollectionView.cs
- NavigatorOutput.cs
- UpDownEvent.cs
- HttpsHostedTransportConfiguration.cs
- SizeLimitedCache.cs
- XmlQueryOutput.cs
- Slider.cs
- VectorKeyFrameCollection.cs
- Filter.cs
- ShapeTypeface.cs
- Condition.cs
- SqlProcedureAttribute.cs
- HttpException.cs
- documentsequencetextview.cs
- AssociationProvider.cs
- PersonalizationProviderHelper.cs
- ProfileParameter.cs
- RegistrySecurity.cs
- ObjectViewQueryResultData.cs
- PagePropertiesChangingEventArgs.cs
- HttpRequestCacheValidator.cs
- StoreAnnotationsMap.cs
- SqlMethodAttribute.cs
- NumericUpDownAcceleration.cs
- SizeValueSerializer.cs
- NavigationProperty.cs
- TcpAppDomainProtocolHandler.cs
- ObjectQuery.cs
- HashCryptoHandle.cs
- PathTooLongException.cs
- DodSequenceMerge.cs
- ColorContextHelper.cs
- TreeViewEvent.cs
- XmlDictionary.cs
- SiteMapHierarchicalDataSourceView.cs
- TextOnlyOutput.cs
- DataGridViewRowsAddedEventArgs.cs
- InputLanguage.cs
- DnsPermission.cs
- ISAPIWorkerRequest.cs
- IDReferencePropertyAttribute.cs
- Msec.cs
- Control.cs
- DataKeyCollection.cs
- InstanceKey.cs
- NullableDoubleSumAggregationOperator.cs
- mansign.cs
- X509LogoTypeExtension.cs
- SqlInternalConnection.cs
- CursorInteropHelper.cs
- XamlSerializerUtil.cs
- FamilyTypefaceCollection.cs
- JapaneseLunisolarCalendar.cs
- ServiceOperationViewControl.cs
- ChunkedMemoryStream.cs
- MembershipUser.cs
- BaseParser.cs
- RepeatButton.cs
- StatusBarItem.cs
- CompensateDesigner.cs
- ResponseBodyWriter.cs
- SQLBytes.cs
- UIElement.cs
- TypeBinaryExpression.cs
- HandledMouseEvent.cs
- PageEventArgs.cs
- PackageRelationshipCollection.cs
- SqlExpander.cs
- PackageStore.cs
- GridViewDeleteEventArgs.cs
- CodeCatchClause.cs
- CodeRegionDirective.cs
- CompositeDataBoundControl.cs
- RayMeshGeometry3DHitTestResult.cs
- GenericsInstances.cs
- XmlDataLoader.cs
- QueueAccessMode.cs
- UnsettableComboBox.cs
- ResolveMatchesMessage11.cs
- LambdaCompiler.ControlFlow.cs
- SystemInformation.cs
- BasicSecurityProfileVersion.cs
- TextRangeAdaptor.cs
- ExpandSegmentCollection.cs
- TreeBuilderBamlTranslator.cs
- HttpCapabilitiesSectionHandler.cs
- FileSystemInfo.cs
- ChtmlCommandAdapter.cs
- ResXResourceWriter.cs
- DataServiceQuery.cs
- HtmlInputImage.cs
- CfgRule.cs
- diagnosticsswitches.cs
- RtfControlWordInfo.cs
- PassportIdentity.cs
- DateRangeEvent.cs
- NumericUpDownAcceleration.cs