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
- ListViewTableCell.cs
- AlternateViewCollection.cs
- CodeVariableReferenceExpression.cs
- WinFormsSpinner.cs
- SQLUtility.cs
- ComponentResourceManager.cs
- FormatterConverter.cs
- XPathDocumentNavigator.cs
- XmlCompatibilityReader.cs
- TypeConverter.cs
- AlphabeticalEnumConverter.cs
- DataControlFieldCell.cs
- PageRequestManager.cs
- HtmlInputText.cs
- TimeStampChecker.cs
- DataSourceCollectionBase.cs
- PointValueSerializer.cs
- OuterGlowBitmapEffect.cs
- Relationship.cs
- NegotiateStream.cs
- MarkupObject.cs
- VisualTarget.cs
- PropertyInformation.cs
- DataSourceGeneratorException.cs
- CodeVariableReferenceExpression.cs
- SqlUserDefinedAggregateAttribute.cs
- HtmlHead.cs
- TextEffect.cs
- DesignerOptionService.cs
- InputManager.cs
- SystemInfo.cs
- sqlnorm.cs
- ChannelReliableSession.cs
- SecureStringHasher.cs
- DPAPIProtectedConfigurationProvider.cs
- ExtensionMethods.cs
- BridgeDataRecord.cs
- Effect.cs
- DirectionalLight.cs
- FixedSOMFixedBlock.cs
- NativeMethods.cs
- TextContainerHelper.cs
- Decimal.cs
- PersonalizationDictionary.cs
- COM2TypeInfoProcessor.cs
- CompatibleIComparer.cs
- LogicalExpr.cs
- LoginUtil.cs
- XmlSchemaAnyAttribute.cs
- SourceFileBuildProvider.cs
- DependencyObject.cs
- AdapterUtil.cs
- Repeater.cs
- ReturnEventArgs.cs
- DefaultMemberAttribute.cs
- BaseValidatorDesigner.cs
- FtpWebRequest.cs
- EmbeddedMailObject.cs
- SrgsSubset.cs
- ResourcePart.cs
- GenericPrincipal.cs
- XPathEmptyIterator.cs
- GridErrorDlg.cs
- Model3D.cs
- FrameworkEventSource.cs
- XmlSiteMapProvider.cs
- ImportContext.cs
- PriorityQueue.cs
- WindowsGraphics2.cs
- ApplicationCommands.cs
- StrokeRenderer.cs
- StateRuntime.cs
- StatusBarItemAutomationPeer.cs
- XmlProcessingInstruction.cs
- ControllableStoryboardAction.cs
- DCSafeHandle.cs
- PermissionRequestEvidence.cs
- HyperLinkStyle.cs
- MediaPlayerState.cs
- ExpressionsCollectionEditor.cs
- AccessibleObject.cs
- WorkflowControlClient.cs
- MetadataException.cs
- CommandLibraryHelper.cs
- FontDialog.cs
- SectionInformation.cs
- FontInfo.cs
- DataViewSettingCollection.cs
- SymbolPair.cs
- COM2PictureConverter.cs
- NavigationEventArgs.cs
- QueryExecutionOption.cs
- TraceFilter.cs
- TextTabProperties.cs
- TypeValidationEventArgs.cs
- WindowsFormsHelpers.cs
- PathGradientBrush.cs
- Point4DValueSerializer.cs
- Hashtable.cs
- PlatformCulture.cs