Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Net / System / Net / Sockets / UDPClient.cs / 1 / UDPClient.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Net.Sockets { using System.Threading; using System.Security.Permissions; ////// public class UdpClient : IDisposable { private const int MaxUDPSize = 0x10000; private Socket m_ClientSocket; private bool m_Active; private byte[] m_Buffer = new byte[MaxUDPSize]; ////// The ///class provides access to UDP services at a /// higher abstraction level than the class. /// is used to connect to a remote host and to receive connections from a remote /// Client. /// /// private AddressFamily m_Family = AddressFamily.InterNetwork; // bind to arbitrary IP+Port ////// Address family for the client, defaults to IPv4. /// ////// public UdpClient() : this(AddressFamily.InterNetwork){ } ////// Initializes a new instance of the ///class. /// /// public UdpClient(AddressFamily family) { // // Validate the address family // if ( family != AddressFamily.InterNetwork && family != AddressFamily.InterNetworkV6 ) { throw new ArgumentException(SR.GetString(SR.net_protocol_invalid_family, "UDP"), "family"); } m_Family = family; createClientSocket(); } // bind specific port, arbitrary IP ////// Initializes a new instance of the ///class. /// /// /// We should obsolete this. This also breaks IPv6-only scenarios. /// But fixing it has many complications that we have decided not /// to fix it and instead obsolete it post-Orcas. public UdpClient(int port) : this(port,AddressFamily.InterNetwork) { } ////// Creates a new instance of the UdpClient class that communicates on the /// specified port number. /// ////// public UdpClient(int port,AddressFamily family) { // // parameter validation // if (!ValidationHelper.ValidateTcpPort(port)) { throw new ArgumentOutOfRangeException("port"); } // // Validate the address family // if ( family != AddressFamily.InterNetwork && family != AddressFamily.InterNetworkV6 ) { throw new ArgumentException(SR.GetString(SR.net_protocol_invalid_family), "family"); } IPEndPoint localEP; m_Family = family; if ( m_Family == AddressFamily.InterNetwork ) { localEP = new IPEndPoint(IPAddress.Any, port); } else { localEP = new IPEndPoint(IPAddress.IPv6Any, port); } createClientSocket(); Client.Bind(localEP); } // bind to given local endpoint ////// Creates a new instance of the UdpClient class that communicates on the /// specified port number. /// ////// public UdpClient(IPEndPoint localEP) { // // parameter validation // if (localEP == null) { throw new ArgumentNullException("localEP"); } // // IPv6 Changes: Set the AddressFamily of this object before // creating the client socket. // m_Family = localEP.AddressFamily; createClientSocket(); Client.Bind(localEP); } // bind and connect ////// Creates a new instance of the UdpClient class that communicates on the /// specified end point. /// ////// public UdpClient(string hostname, int port) { // // parameter validation // if (hostname == null) { throw new ArgumentNullException("hostname"); } if (!ValidationHelper.ValidateTcpPort(port)) { throw new ArgumentOutOfRangeException("port"); } // // NOTE: Need to create different kinds of sockets based on the addresses // returned from DNS. As a result, we defer the creation of the // socket until the Connect method. // //createClientSocket(); Connect(hostname, port); } ////// Creates a new instance of the ///class and connects to the /// specified remote host on the specified port. /// /// public Socket Client { get { return m_ClientSocket; } set { m_ClientSocket = value; } } ////// Used by the class to provide the underlying network socket. /// ////// protected bool Active { get { return m_Active; } set { m_Active = value; } } public int Available{ get{ return m_ClientSocket.Available; } } public short Ttl{ get{ return m_ClientSocket.Ttl; } set{ m_ClientSocket.Ttl = value; } } //new public bool DontFragment{ get{ return m_ClientSocket.DontFragment; } set{ m_ClientSocket.DontFragment = value; } } //new public bool MulticastLoopback{ get{ return m_ClientSocket.MulticastLoopback; } set{ m_ClientSocket.MulticastLoopback = value; } } //new public bool EnableBroadcast{ get{ return m_ClientSocket.EnableBroadcast; } set{ m_ClientSocket.EnableBroadcast = value; } } //new public bool ExclusiveAddressUse { get{ return m_ClientSocket.ExclusiveAddressUse; } set{ m_ClientSocket.ExclusiveAddressUse = value; } } //new public void Close() { Dispose(true); } private bool m_CleanedUp = false; private void FreeResources() { // // only resource we need to free is the network stream, since this // is based on the client socket, closing the stream will cause us // to flush the data to the network, close the stream and (in the // NetoworkStream code) close the socket as well. // if (m_CleanedUp) { return; } Socket chkClientSocket = Client; if (chkClientSocket!=null) { // // if the NetworkStream wasn't retrieved, the Socket might // still be there and needs to be closed to release the effect // of the Bind() call and free the bound IPEndPoint. // chkClientSocket.InternalShutdown(SocketShutdown.Both); chkClientSocket.Close(); Client = null; } m_CleanedUp = true; } ////// Used by the class to indicate that a connection to a remote host has been /// made. /// ///void IDisposable.Dispose() { Dispose(true); } protected virtual void Dispose(bool disposing) { if (disposing) { GlobalLog.Print("UdpClient::Dispose()"); FreeResources(); GC.SuppressFinalize(this); } } /// /// public void Connect(string hostname, int port){ // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if (hostname == null){ throw new ArgumentNullException("hostname"); } if (!ValidationHelper.ValidateTcpPort(port)){ throw new ArgumentOutOfRangeException("port"); } // // IPv6 Changes: instead of just using the first address in the list, // we must now look for addresses that use a compatible // address family to the client socket. // However, in the case of the/// Establishes a connection to the specified port on the /// specified host. /// ///constructor // we will have deferred creating the socket and will // do that here instead. // In addition, the redundant CheckForBroadcast call was // removed here since it is called from Connect(). // IPAddress[] addresses = Dns.GetHostAddresses(hostname); Exception lastex = null; Socket ipv6Socket = null; Socket ipv4Socket = null; try { if (m_ClientSocket == null){ if (Socket.SupportsIPv4){ ipv4Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); } if (Socket.OSSupportsIPv6){ ipv6Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp); } } foreach (IPAddress address in addresses) { try { if (m_ClientSocket == null) { // // We came via the constructor. Set the // address family appropriately, create the socket and // try to connect. // if (address.AddressFamily == AddressFamily.InterNetwork && ipv4Socket != null) { ipv4Socket.Connect(address, port); m_ClientSocket = ipv4Socket; if (ipv6Socket != null) ipv6Socket.Close(); } else if (ipv6Socket != null) { ipv6Socket.Connect(address, port); m_ClientSocket = ipv6Socket; if (ipv4Socket != null) ipv4Socket.Close(); } m_Family = address.AddressFamily; m_Active = true; break; } else if (address.AddressFamily == m_Family) { // // Only use addresses with a matching family // Connect(new IPEndPoint(address, port)); m_Active = true; break; } } catch ( Exception ex ) { if (NclUtilities.IsFatal(ex)) { throw; } lastex = ex; } } } catch (Exception ex){ if (NclUtilities.IsFatal(ex)) { throw; } lastex = ex; } finally { //cleanup temp sockets if failed //main socket gets closed when tcpclient gets closed //did we connect? if (!m_Active) { if (ipv6Socket != null){ ipv6Socket.Close(); } if (ipv4Socket != null){ ipv4Socket.Close(); } // // The connect failed - rethrow the last error we had // if (lastex != null) throw lastex; else throw new SocketException(SocketError.NotConnected); } } } /// /// public void Connect(IPAddress addr, int port) { // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if (addr==null){ throw new ArgumentNullException("addr"); } if (!ValidationHelper.ValidateTcpPort(port)) { throw new ArgumentOutOfRangeException("port"); } // // IPv6 Changes: Removed redundant call to CheckForBroadcast() since // it is made in the real Connect() method. // IPEndPoint endPoint = new IPEndPoint(addr, port); Connect(endPoint); } ////// Establishes a connection with the host at the specified address on the /// specified port. /// ////// public void Connect(IPEndPoint endPoint) { // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if (endPoint==null){ throw new ArgumentNullException("endPoint"); } // // IPv6 Changes: Actually, no changes but we might want to check for // compatible protocols here rather than push it down // to WinSock. // CheckForBroadcast(endPoint.Address); Client.Connect(endPoint); m_Active = true; } private bool m_IsBroadcast; private void CheckForBroadcast(IPAddress ipAddress) { // // Here we check to see if the user is trying to use a Broadcast IP address // we only detect IPAddress.Broadcast (which is not the only Broadcast address) // and in that case we set SocketOptionName.Broadcast on the socket to allow its use. // if the user really wants complete control over Broadcast addresses he needs to // inherit from UdpClient and gain control over the Socket and do whatever is appropriate. // if (Client!=null && !m_IsBroadcast && ipAddress.IsBroadcast) { // // we need to set the Broadcast socket option. // note that, once we set the option on the Socket, we never reset it. // m_IsBroadcast = true; Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); } } ////// Establishes a connection to a remote end point. /// ////// public int Send(byte[] dgram, int bytes, IPEndPoint endPoint) { // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if (dgram==null){ throw new ArgumentNullException("dgram"); } if (m_Active && endPoint!=null) { // // Do not allow sending packets to arbitrary host when connected // throw new InvalidOperationException(SR.GetString(SR.net_udpconnected)); } if (endPoint==null) { return Client.Send(dgram, 0, bytes, SocketFlags.None); } CheckForBroadcast(endPoint.Address); return Client.SendTo(dgram, 0, bytes, SocketFlags.None, endPoint); } ////// Sends a UDP datagram to the host at the remote end point. /// ////// public int Send(byte[] dgram, int bytes, string hostname, int port) { // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if (dgram==null){ throw new ArgumentNullException("dgram"); } if (m_Active && ((hostname != null) || (port != 0))) { // // Do not allow sending packets to arbitrary host when connected // throw new InvalidOperationException(SR.GetString(SR.net_udpconnected)); } if (hostname==null || port==0) { return Client.Send(dgram, 0, bytes, SocketFlags.None); } IPAddress[] addresses = Dns.GetHostAddresses(hostname); int i=0; for (;i/// Sends a UDP datagram to the specified port on the specified remote host. /// ////// /// Sends a UDP datagram to a /// remote host. /// /// public int Send(byte[] dgram, int bytes) { // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if (dgram==null){ throw new ArgumentNullException("dgram"); } if (!m_Active) { // // only allowed on connected socket // throw new InvalidOperationException(SR.GetString(SR.net_notconnected)); } return Client.Send(dgram, 0, bytes, SocketFlags.None); } [HostProtection(ExternalThreading=true)] public IAsyncResult BeginSend(byte[] datagram, int bytes, IPEndPoint endPoint, AsyncCallback requestCallback, object state) { // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if (datagram==null){ throw new ArgumentNullException("datagram"); } if (bytes > datagram.Length) { throw new ArgumentOutOfRangeException("bytes"); } if (m_Active && endPoint!=null) { // // Do not allow sending packets to arbitrary host when connected // throw new InvalidOperationException(SR.GetString(SR.net_udpconnected)); } if (endPoint==null) { return Client.BeginSend(datagram, 0, bytes, SocketFlags.None, requestCallback, state); } CheckForBroadcast(endPoint.Address); return Client.BeginSendTo(datagram, 0, bytes, SocketFlags.None, endPoint, requestCallback, state); } [HostProtection(ExternalThreading=true)] public IAsyncResult BeginSend(byte[] datagram, int bytes, string hostname, int port, AsyncCallback requestCallback, object state) { if (m_Active && ((hostname != null) || (port != 0))) { // Do not allow sending packets to arbitrary host when connected throw new InvalidOperationException(SR.GetString(SR.net_udpconnected)); } IPEndPoint ipEndPoint = null; if (hostname!=null && port!=0) { IPAddress[] addresses = Dns.GetHostAddresses(hostname); int i=0; for (;i/// /// Returns a datagram sent by a server. /// /// public byte[] Receive(ref IPEndPoint remoteEP) { // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // this is a fix due to the nature of the ReceiveFrom() call and the // ref parameter convention, we need to cast an IPEndPoint to it's base // class EndPoint and cast it back down to IPEndPoint. ugly but it works. // EndPoint tempRemoteEP; if ( m_Family == AddressFamily.InterNetwork ) { tempRemoteEP = IPEndPoint.Any; } else { tempRemoteEP = IPEndPoint.IPv6Any; } int received = Client.ReceiveFrom(m_Buffer, MaxUDPSize, 0 , ref tempRemoteEP); remoteEP = (IPEndPoint)tempRemoteEP; // because we don't return the actual length, we need to ensure the returned buffer // has the appropriate length. if (received < MaxUDPSize) { byte[] newBuffer = new byte[received]; Buffer.BlockCopy(m_Buffer,0,newBuffer,0,received); return newBuffer; } return m_Buffer; } [HostProtection(ExternalThreading=true)] public IAsyncResult BeginReceive(AsyncCallback requestCallback, object state) { // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // this is a fix due to the nature of the ReceiveFrom() call and the // ref parameter convention, we need to cast an IPEndPoint to it's base // class EndPoint and cast it back down to IPEndPoint. ugly but it works. // EndPoint tempRemoteEP; if ( m_Family == AddressFamily.InterNetwork ) { tempRemoteEP = IPEndPoint.Any; } else { tempRemoteEP = IPEndPoint.IPv6Any; } return Client.BeginReceiveFrom(m_Buffer, 0, MaxUDPSize, SocketFlags.None , ref tempRemoteEP, requestCallback, state); } public byte[] EndReceive(IAsyncResult asyncResult, ref IPEndPoint remoteEP){ if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } EndPoint tempRemoteEP; if ( m_Family == AddressFamily.InterNetwork ) { tempRemoteEP = IPEndPoint.Any; } else { tempRemoteEP = IPEndPoint.IPv6Any; } int received = Client.EndReceiveFrom(asyncResult,ref tempRemoteEP); remoteEP = (IPEndPoint)tempRemoteEP; // because we don't return the actual length, we need to ensure the returned buffer // has the appropriate length. if (received < MaxUDPSize) { byte[] newBuffer = new byte[received]; Buffer.BlockCopy(m_Buffer,0,newBuffer,0,received); return newBuffer; } return m_Buffer; } ////// public void JoinMulticastGroup(IPAddress multicastAddr) { // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if (multicastAddr==null){ throw new ArgumentNullException("multicastAddr"); } // // IPv6 Changes: we need to create the correct MulticastOption and // must also check for address family compatibility // if ( multicastAddr.AddressFamily != m_Family ) { throw new ArgumentException(SR.GetString(SR.net_protocol_invalid_multicast_family, "UDP"), "multicastAddr"); } if ( m_Family == AddressFamily.InterNetwork ) { MulticastOption mcOpt = new MulticastOption(multicastAddr); Client.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.AddMembership, mcOpt ); } else { IPv6MulticastOption mcOpt = new IPv6MulticastOption(multicastAddr); Client.SetSocketOption( SocketOptionLevel.IPv6, SocketOptionName.AddMembership, mcOpt ); } } public void JoinMulticastGroup(IPAddress multicastAddr, IPAddress localAddress) { // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if ( m_Family != AddressFamily.InterNetwork ) { throw new SocketException(SocketError.OperationNotSupported); } MulticastOption mcOpt = new MulticastOption(multicastAddr,localAddress); Client.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.AddMembership, mcOpt ); } ////// Joins a multicast address group. /// ////// public void JoinMulticastGroup(int ifindex,IPAddress multicastAddr) { // // parameter validation // if ( m_CleanedUp ){ throw new ObjectDisposedException(this.GetType().FullName); } if ( multicastAddr==null ) { throw new ArgumentNullException("multicastAddr"); } if ( ifindex < 0 ) { throw new ArgumentException(SR.GetString(SR.net_value_cannot_be_negative), "ifindex"); } // // Ensure that this is an IPv6 client, otherwise throw WinSock // Operation not supported socked exception. // if ( m_Family != AddressFamily.InterNetworkV6 ) { throw new SocketException(SocketError.OperationNotSupported); } IPv6MulticastOption mcOpt = new IPv6MulticastOption(multicastAddr,ifindex); Client.SetSocketOption( SocketOptionLevel.IPv6, SocketOptionName.AddMembership, mcOpt ); } ////// Joins an IPv6 multicast address group. /// ////// public void JoinMulticastGroup(IPAddress multicastAddr, int timeToLive) { // // parameter validation; // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if (multicastAddr==null){ throw new ArgumentNullException("multicastAddr"); } if (!ValidationHelper.ValidateRange(timeToLive, 0, 255)) { throw new ArgumentOutOfRangeException("timeToLive"); } // // join the Multicast Group // JoinMulticastGroup(multicastAddr); // // set Time To Live (TLL) // Client.SetSocketOption( (m_Family == AddressFamily.InterNetwork) ? SocketOptionLevel.IP : SocketOptionLevel.IPv6, SocketOptionName.MulticastTimeToLive, timeToLive ); } ////// Joins a multicast address group with the specified time to live (TTL). /// ////// public void DropMulticastGroup(IPAddress multicastAddr) { // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if (multicastAddr==null){ throw new ArgumentNullException("multicastAddr"); } // // IPv6 Changes: we need to create the correct MulticastOption and // must also check for address family compatibility // if ( multicastAddr.AddressFamily != m_Family ) { throw new ArgumentException(SR.GetString(SR.net_protocol_invalid_multicast_family, "UDP"), "multicastAddr"); } if ( m_Family == AddressFamily.InterNetwork ) { MulticastOption mcOpt = new MulticastOption(multicastAddr); Client.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.DropMembership, mcOpt ); } else { IPv6MulticastOption mcOpt = new IPv6MulticastOption(multicastAddr); Client.SetSocketOption( SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mcOpt ); } } ////// Leaves a multicast address group. /// ////// public void DropMulticastGroup(IPAddress multicastAddr,int ifindex) { // // parameter validation // if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } if ( multicastAddr==null ) { throw new ArgumentNullException("multicastAddr"); } if ( ifindex < 0 ) { throw new ArgumentException(SR.GetString(SR.net_value_cannot_be_negative), "ifindex"); } // // Ensure that this is an IPv6 client, otherwise throw WinSock // Operation not supported socked exception. // if ( m_Family != AddressFamily.InterNetworkV6 ) { throw new SocketException(SocketError.OperationNotSupported); } IPv6MulticastOption mcOpt = new IPv6MulticastOption(multicastAddr,ifindex); Client.SetSocketOption( SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mcOpt ); } private void createClientSocket() { // // common initialization code // // IPv6 Changes: Use the AddressFamily of this class rather than hardcode. // Client = new Socket(m_Family, SocketType.Dgram, ProtocolType.Udp); } } // class UdpClient } // namespace System.Net.Sockets/// Leaves an IPv6 multicast address group. /// ///
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FileFormatException.cs
- ToolStripMenuItemCodeDomSerializer.cs
- DataMisalignedException.cs
- JsonDeserializer.cs
- SchemaCollectionCompiler.cs
- EntityDataSourceEntityTypeFilterConverter.cs
- TextServicesCompartmentEventSink.cs
- ComplexBindingPropertiesAttribute.cs
- MetabaseServerConfig.cs
- ReflectionUtil.cs
- ResourceIDHelper.cs
- DispatcherHooks.cs
- HttpWebResponse.cs
- DataControlCommands.cs
- OleDbException.cs
- BaseValidator.cs
- UrlPropertyAttribute.cs
- EntityDataSourceStatementEditor.cs
- CompilationRelaxations.cs
- RepeatButton.cs
- ParameterBuilder.cs
- XmlMtomReader.cs
- StringWriter.cs
- ClientBuildManager.cs
- SafeNativeMethods.cs
- RuntimeVariablesExpression.cs
- FlowDocumentPageViewerAutomationPeer.cs
- Form.cs
- TypographyProperties.cs
- StorageSetMapping.cs
- __Filters.cs
- securestring.cs
- SafeBitVector32.cs
- DbConnectionInternal.cs
- PixelFormat.cs
- DataTableCollection.cs
- HttpHostedTransportConfiguration.cs
- XmlDataLoader.cs
- ObjectDataSourceDisposingEventArgs.cs
- HotSpotCollection.cs
- SQlBooleanStorage.cs
- XmlByteStreamWriter.cs
- AlphabetConverter.cs
- Size.cs
- RegularExpressionValidator.cs
- SafeMemoryMappedViewHandle.cs
- SourceInterpreter.cs
- SingleKeyFrameCollection.cs
- DataBindingHandlerAttribute.cs
- DataGridViewImageColumn.cs
- TimeSpanOrInfiniteConverter.cs
- FaultFormatter.cs
- DistinctQueryOperator.cs
- EncryptedType.cs
- NotificationContext.cs
- RNGCryptoServiceProvider.cs
- ParentUndoUnit.cs
- SHA1Managed.cs
- FunctionQuery.cs
- AmbientLight.cs
- CodeTypeMember.cs
- FormViewDeleteEventArgs.cs
- EntityDataSourceEntitySetNameItem.cs
- SqlBuilder.cs
- ContainerControlDesigner.cs
- StatusBar.cs
- DataMisalignedException.cs
- StateItem.cs
- BoundsDrawingContextWalker.cs
- XamlReaderHelper.cs
- ListViewDeleteEventArgs.cs
- AuthenticateEventArgs.cs
- InvokeProviderWrapper.cs
- IdentityNotMappedException.cs
- DataGridPagerStyle.cs
- TextFormatterContext.cs
- ContainerSelectorGlyph.cs
- TypeListConverter.cs
- VirtualDirectoryMapping.cs
- SafeRightsManagementPubHandle.cs
- VoiceInfo.cs
- MultipartIdentifier.cs
- Drawing.cs
- VisemeEventArgs.cs
- MediaScriptCommandRoutedEventArgs.cs
- IISUnsafeMethods.cs
- SpeakProgressEventArgs.cs
- HttpClientCertificate.cs
- ZipIOCentralDirectoryFileHeader.cs
- FormsAuthenticationConfiguration.cs
- ClassDataContract.cs
- StringCollection.cs
- BamlLocalizerErrorNotifyEventArgs.cs
- TypeConstant.cs
- SystemSounds.cs
- MenuItemBinding.cs
- BuildManagerHost.cs
- ZipIOExtraField.cs
- InvokeHandlers.cs
- ColorIndependentAnimationStorage.cs