The Labs \ Source Viewer \ SSCLI \ System.Runtime.Remoting.Channels \ ExclusiveTcpListener

  1. //------------------------------------------------------------------------------
  2. // <copyright file="ExclusiveTcpListener.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. using System;
  16. using System.Net;
  17. using System.Net.Sockets;
  18. namespace System.Runtime.Remoting.Channels
  19. {
  20.    
  21.     // This class provides a TcpListener that is capable of setting the ExclusiveAddressUse flag
  22.     // on a socket, which will prevent another app from hijacking our port. This flag is not supported
  23.     // on Win9x, so we just omit the call to SetSocketOption on non-NT platforms.
  24.     internal class ExclusiveTcpListener : TcpListener
  25.     {
  26.         internal ExclusiveTcpListener(IPAddress localaddr, int port) : base(localaddr, port)
  27.         {
  28.         }
  29.        
  30.         // Start will attempt to start listening. If exclusiveAddressUse is true, then
  31.         // we will attempt to use the ExclusiveAddressUse flag, but if bind fails (which will
  32.         // happen for a regular user on win2k and xp), we try again without the flag.
  33.         internal void Start(bool exclusiveAddressUse)
  34.         {
  35.             // we only attempt to set the socket option if
  36.             // 1. the exclusiveAddressUse param is true
  37.             // 2. the platform is NT - this option is unavailable on other platforms
  38.             // 3. Server is not null - if it IS null, base.Start will throw a nice error for us
  39.             // 4. the listener is not already listening - it's too late in that case (base.Start will return immediately)
  40.             bool attemptSetSocketOption = exclusiveAddressUse && base.Server != null && !base.Active;
  41.            
  42.             if (attemptSetSocketOption) {
  43.                 // Attempt to set the option. We won't actually find out if this fails until
  44.                 // we try to bind (which happens in base.Start()).
  45.                 base.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, 1);
  46.             }
  47.            
  48.             try {
  49.                 base.Start();
  50.             }
  51.             catch (SocketException) {
  52.                 if (attemptSetSocketOption) {
  53.                     // Turn off the option and try again - maybe this process doesn't have
  54.                     // permission to use the option.
  55.                     Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, 0);
  56.                     base.Start();
  57.                 }
  58.                 else {
  59.                     // It wasn't because we set the ExclusiveAddressUse option - let the
  60.                     // exception bubble up
  61.                     throw;
  62.                 }
  63.             }
  64.         }
  65.        
  66.         internal bool IsListening {
  67.             get { return Active; }
  68.         }
  69.        
  70.     }
  71.    
  72. }
  73. // namespace System.Runtime.Remoting.Channels

Developer Fusion