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
- ToolStripSystemRenderer.cs
- ToolboxItemAttribute.cs
- ComContractElementCollection.cs
- EventWaitHandle.cs
- ObjectView.cs
- MetadataArtifactLoaderXmlReaderWrapper.cs
- DynamicPropertyHolder.cs
- OLEDB_Util.cs
- DynamicValidator.cs
- PowerStatus.cs
- DoubleLinkListEnumerator.cs
- WinCategoryAttribute.cs
- SqlRemoveConstantOrderBy.cs
- BaseValidator.cs
- SByteStorage.cs
- CollectionEditVerbManager.cs
- GetPageCompletedEventArgs.cs
- MarginsConverter.cs
- Descriptor.cs
- DownloadProgressEventArgs.cs
- SchemaCollectionCompiler.cs
- DataObject.cs
- ControlTemplate.cs
- RegexStringValidatorAttribute.cs
- XmlHierarchicalDataSourceView.cs
- BlurBitmapEffect.cs
- ConfigXmlComment.cs
- IndentedWriter.cs
- ServiceNameElement.cs
- objectquery_tresulttype.cs
- EdgeProfileValidation.cs
- NetworkAddressChange.cs
- MarkupWriter.cs
- AspNetHostingPermission.cs
- DnsPermission.cs
- PartManifestEntry.cs
- SiteMapNodeCollection.cs
- WebControlAdapter.cs
- DesignTimeParseData.cs
- SystemIPv6InterfaceProperties.cs
- ExpandedProjectionNode.cs
- RunInstallerAttribute.cs
- SettingsAttributeDictionary.cs
- GenericTypeParameterBuilder.cs
- Delegate.cs
- PeerResolver.cs
- XmlConvert.cs
- FreeFormPanel.cs
- DSASignatureFormatter.cs
- ProxyAttribute.cs
- DictionaryManager.cs
- DataRowComparer.cs
- ContractSearchPattern.cs
- EndpointAddress.cs
- StorageEntityTypeMapping.cs
- NamespaceCollection.cs
- ObjectViewFactory.cs
- __Filters.cs
- WaitHandleCannotBeOpenedException.cs
- DescendentsWalkerBase.cs
- ToolstripProfessionalRenderer.cs
- FilteredDataSetHelper.cs
- InputManager.cs
- WindowsToolbar.cs
- GradientSpreadMethodValidation.cs
- sortedlist.cs
- Menu.cs
- FixUpCollection.cs
- TemplateControlParser.cs
- ButtonField.cs
- ConnectionPoint.cs
- DataGridViewRowCollection.cs
- HwndSourceKeyboardInputSite.cs
- ADConnectionHelper.cs
- Win32Exception.cs
- SafeNativeMethodsMilCoreApi.cs
- ExpressionDumper.cs
- BindableTemplateBuilder.cs
- SoapParser.cs
- Command.cs
- EntitySqlQueryBuilder.cs
- WebPartVerbsEventArgs.cs
- SqlFormatter.cs
- MergeFailedEvent.cs
- AutoSizeComboBox.cs
- LabelAutomationPeer.cs
- GridItemCollection.cs
- ColorIndependentAnimationStorage.cs
- CreatingCookieEventArgs.cs
- UICuesEvent.cs
- ChangeBlockUndoRecord.cs
- Bitmap.cs
- Span.cs
- CalendarButton.cs
- GridItemProviderWrapper.cs
- PersistenceException.cs
- DateTimeFormatInfo.cs
- FormsAuthentication.cs
- UserControl.cs
- DataContext.cs