The Labs \ Source Viewer \ SSCLI \ System.Net.Sockets \ TcpListener

  1. //------------------------------------------------------------------------------
  2. // <copyright file="TCPListener.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. namespace System.Net.Sockets
  16. {
  17.     using System;
  18.     using System.Net;
  19.     using System.Security.Permissions;
  20.    
  21.     /// <devdoc>
  22.     /// <para>The <see cref='System.Net.Sockets.TcpListener'/> class provide TCP services at a higher level of abstraction than the <see cref='System.Net.Sockets.Socket'/>
  23.     /// class. <see cref='System.Net.Sockets.TcpListener'/> is used to create a host process that
  24.     /// listens for connections from TCP clients.</para>
  25.     /// </devdoc>
  26.     public class TcpListener
  27.     {
  28.        
  29.         IPEndPoint m_ServerSocketEP;
  30.         Socket m_ServerSocket;
  31.         bool m_Active;
  32.         bool m_ExclusiveAddressUse;
  33.        
  34.        
  35.        
  36.        
  37.         /// <devdoc>
  38.         /// <para>
  39.         /// Initializes a new instance of the TcpListener class with the specified local
  40.         /// end point.
  41.         /// </para>
  42.         /// </devdoc>
  43.         public TcpListener(IPEndPoint localEP)
  44.         {
  45.             if (Logging.On)
  46.                 Logging.Enter(Logging.Sockets, this, "TcpListener", localEP);
  47.             if (localEP == null) {
  48.                 throw new ArgumentNullException("localEP");
  49.             }
  50.             m_ServerSocketEP = localEP;
  51.             m_ServerSocket = new Socket(m_ServerSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  52.             if (Logging.On)
  53.                 Logging.Exit(Logging.Sockets, this, "TcpListener", null);
  54.         }
  55.        
  56.         /// <devdoc>
  57.         /// <para>
  58.         /// Initializes a new instance of the TcpListener class that listens to the
  59.         /// specified IP address and port.
  60.         /// </para>
  61.         /// </devdoc>
  62.         public TcpListener(IPAddress localaddr, int port)
  63.         {
  64.             if (Logging.On)
  65.                 Logging.Enter(Logging.Sockets, this, "TcpListener", localaddr);
  66.             if (localaddr == null) {
  67.                 throw new ArgumentNullException("localaddr");
  68.             }
  69.             if (!ValidationHelper.ValidateTcpPort(port)) {
  70.                 throw new ArgumentOutOfRangeException("port");
  71.             }
  72.             m_ServerSocketEP = new IPEndPoint(localaddr, port);
  73.             m_ServerSocket = new Socket(m_ServerSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  74.             if (Logging.On)
  75.                 Logging.Exit(Logging.Sockets, this, "TcpListener", null);
  76.         }
  77.        
  78.         // implementation picks an address for client
  79.         /// <devdoc>
  80.         /// <para>
  81.         /// Initiailizes a new instance of the TcpListener class
  82.         /// that listens on the specified
  83.         /// port.
  84.         /// </para>
  85.         /// </devdoc>
  86.         ///
  87.        
  88.         [Obsolete("This method has been deprecated. Please use TcpListener(IPAddress localaddr, int port) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
  89.         public TcpListener(int port)
  90.         {
  91.            
  92.             if (!ValidationHelper.ValidateTcpPort(port))
  93.                 throw new ArgumentOutOfRangeException("port");
  94.            
  95.             m_ServerSocketEP = new IPEndPoint(IPAddress.Any, port);
  96.             m_ServerSocket = new Socket(m_ServerSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  97.         }
  98.        
  99.         /// <devdoc>
  100.         /// <para>
  101.         /// Used by the class to provide the underlying network socket.
  102.         /// </para>
  103.         /// </devdoc>
  104.         public Socket Server {
  105.             get { return m_ServerSocket; }
  106.         }
  107.        
  108.         /// <devdoc>
  109.         /// <para>
  110.         /// Used
  111.         /// by the class to indicate that the listener's socket has been bound to a port
  112.         /// and started listening.
  113.         /// </para>
  114.         /// </devdoc>
  115.         protected bool Active {
  116.             get { return m_Active; }
  117.         }
  118.        
  119.         /// <devdoc>
  120.         /// <para>
  121.         /// Gets the m_Active EndPoint for the local listener socket.
  122.         /// </para>
  123.         /// </devdoc>
  124.         public EndPoint LocalEndpoint {
  125.             get { return m_Active ? m_ServerSocket.LocalEndPoint : m_ServerSocketEP; }
  126.         }
  127.        
  128.         public bool ExclusiveAddressUse {
  129.             get { return m_ServerSocket.ExclusiveAddressUse; }
  130.             set {
  131.                 if (m_Active) {
  132.                     throw new InvalidOperationException(SR.GetString(SR.net_tcplistener_mustbestopped));
  133.                 }
  134.                 m_ServerSocket.ExclusiveAddressUse = value;
  135.                 m_ExclusiveAddressUse = value;
  136.             }
  137.         }
  138.        
  139.        
  140.         // Start/stop the listener
  141.         /// <devdoc>
  142.         /// <para>
  143.         /// Starts listening to network requests.
  144.         /// </para>
  145.         /// </devdoc>
  146.         public void Start()
  147.         {
  148.             Start((int)SocketOptionName.MaxConnections);
  149.         }
  150.        
  151.         public void Start(int backlog)
  152.         {
  153.             if (backlog > (int)SocketOptionName.MaxConnections || backlog < 0) {
  154.                 throw new ArgumentOutOfRangeException("backlog");
  155.             }
  156.            
  157.             if (Logging.On)
  158.                 Logging.Enter(Logging.Sockets, this, "Start", null);
  159.             GlobalLog.Print("TCPListener::Start()");
  160.            
  161.             if (m_ServerSocket == null)
  162.                 throw new InvalidOperationException(SR.GetString(SR.net_InvalidSocketHandle));
  163.            
  164.             //already listening
  165.             if (m_Active) {
  166.                 if (Logging.On)
  167.                     Logging.Exit(Logging.Sockets, this, "Start", null);
  168.                 return;
  169.             }
  170.            
  171.             m_ServerSocket.Bind(m_ServerSocketEP);
  172.             m_ServerSocket.Listen(backlog);
  173.             m_Active = true;
  174.             if (Logging.On)
  175.                 Logging.Exit(Logging.Sockets, this, "Start", null);
  176.         }
  177.        
  178.        
  179.         /// <devdoc>
  180.         /// <para>
  181.         /// Closes the network connection.
  182.         /// </para>
  183.         /// </devdoc>
  184.         public void Stop()
  185.         {
  186.             if (Logging.On)
  187.                 Logging.Enter(Logging.Sockets, this, "Stop", null);
  188.             GlobalLog.Print("TCPListener::Stop()");
  189.            
  190.             if (m_ServerSocket != null) {
  191.                 m_ServerSocket.Close();
  192.                 m_ServerSocket = null;
  193.             }
  194.             m_Active = false;
  195.             m_ServerSocket = new Socket(m_ServerSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  196.            
  197.             if (m_ExclusiveAddressUse) {
  198.                 m_ServerSocket.ExclusiveAddressUse = true;
  199.             }
  200.            
  201.             if (Logging.On)
  202.                 Logging.Exit(Logging.Sockets, this, "Stop", null);
  203.         }
  204.        
  205.         // Determine if there are pending connections
  206.         /// <devdoc>
  207.         /// <para>
  208.         /// Determine if there are pending connection requests.
  209.         /// </para>
  210.         /// </devdoc>
  211.         public bool Pending()
  212.         {
  213.             if (!m_Active)
  214.                 throw new InvalidOperationException(SR.GetString(SR.net_stopped));
  215.             return m_ServerSocket.Poll(0, SelectMode.SelectRead);
  216.         }
  217.        
  218.         // Accept the first pending connection
  219.         /// <devdoc>
  220.         /// <para>
  221.         /// Accepts a pending connection request.
  222.         /// </para>
  223.         /// </devdoc>
  224.         public Socket AcceptSocket()
  225.         {
  226.             if (Logging.On)
  227.                 Logging.Enter(Logging.Sockets, this, "AcceptSocket", null);
  228.             if (!m_Active)
  229.                 throw new InvalidOperationException(SR.GetString(SR.net_stopped));
  230.             Socket socket = m_ServerSocket.Accept();
  231.             if (Logging.On)
  232.                 Logging.Exit(Logging.Sockets, this, "AcceptSocket", socket);
  233.             return socket;
  234.         }
  235.        
  236.         // UEUE
  237.         /// <devdoc>
  238.         /// <para>[To be supplied.]</para>
  239.         /// </devdoc>
  240.         public TcpClient AcceptTcpClient()
  241.         {
  242.             if (Logging.On)
  243.                 Logging.Enter(Logging.Sockets, this, "AcceptTcpClient", null);
  244.             if (!m_Active)
  245.                 throw new InvalidOperationException(SR.GetString(SR.net_stopped));
  246.            
  247.             Socket acceptedSocket = m_ServerSocket.Accept();
  248.             TcpClient returnValue = new TcpClient(acceptedSocket);
  249.             if (Logging.On)
  250.                 Logging.Exit(Logging.Sockets, this, "AcceptTcpClient", returnValue);
  251.             return returnValue;
  252.         }
  253.        
  254.        
  255.        
  256.         //methods
  257.        
  258.         [HostProtection(ExternalThreading = true)]
  259.         public IAsyncResult BeginAcceptSocket(AsyncCallback callback, object state)
  260.         {
  261.             if (Logging.On)
  262.                 Logging.Enter(Logging.Sockets, this, "BeginAcceptSocket", null);
  263.             if (!m_Active)
  264.                 throw new InvalidOperationException(SR.GetString(SR.net_stopped));
  265.            
  266.             IAsyncResult result = m_ServerSocket.BeginAccept(callback, state);
  267.             if (Logging.On)
  268.                 Logging.Exit(Logging.Sockets, this, "BeginAcceptSocket", null);
  269.             return result;
  270.         }
  271.        
  272.         public Socket EndAcceptSocket(IAsyncResult asyncResult)
  273.         {
  274.             if (Logging.On)
  275.                 Logging.Enter(Logging.Sockets, this, "EndAcceptSocket", null);
  276.            
  277.             if (asyncResult == null) {
  278.                 throw new ArgumentNullException("asyncResult");
  279.             }
  280.            
  281.             LazyAsyncResult lazyResult = asyncResult as LazyAsyncResult;
  282.             Socket asyncSocket = lazyResult == null ? null : lazyResult.AsyncObject as Socket;
  283.             if (asyncSocket == null) {
  284.                 throw new ArgumentException(SR.GetString(SR.net_io_invalidasyncresult), "asyncResult");
  285.             }
  286.            
  287.             // This will throw ObjectDisposedException if Stop() has been called.
  288.             Socket socket = asyncSocket.EndAccept(asyncResult);
  289.            
  290.             if (Logging.On)
  291.                 Logging.Exit(Logging.Sockets, this, "EndAcceptSocket", socket);
  292.             return socket;
  293.         }
  294.        
  295.         [HostProtection(ExternalThreading = true)]
  296.         public IAsyncResult BeginAcceptTcpClient(AsyncCallback callback, object state)
  297.         {
  298.             if (Logging.On)
  299.                 Logging.Enter(Logging.Sockets, this, "BeginAcceptTcpClient", null);
  300.             if (!m_Active)
  301.                 throw new InvalidOperationException(SR.GetString(SR.net_stopped));
  302.             IAsyncResult result = m_ServerSocket.BeginAccept(callback, state);
  303.             if (Logging.On)
  304.                 Logging.Exit(Logging.Sockets, this, "BeginAcceptTcpClient", null);
  305.             return result;
  306.         }
  307.        
  308.         public TcpClient EndAcceptTcpClient(IAsyncResult asyncResult)
  309.         {
  310.             if (Logging.On)
  311.                 Logging.Enter(Logging.Sockets, this, "EndAcceptTcpClient", null);
  312.            
  313.             if (asyncResult == null) {
  314.                 throw new ArgumentNullException("asyncResult");
  315.             }
  316.            
  317.             LazyAsyncResult lazyResult = asyncResult as LazyAsyncResult;
  318.             Socket asyncSocket = lazyResult == null ? null : lazyResult.AsyncObject as Socket;
  319.             if (asyncSocket == null) {
  320.                 throw new ArgumentException(SR.GetString(SR.net_io_invalidasyncresult), "asyncResult");
  321.             }
  322.            
  323.             // This will throw ObjectDisposedException if Stop() has been called.
  324.             Socket socket = asyncSocket.EndAccept(asyncResult);
  325.            
  326.             if (Logging.On)
  327.                 Logging.Exit(Logging.Sockets, this, "EndAcceptTcpClient", socket);
  328.             return new TcpClient(socket);
  329.         }
  330.     }
  331.     // class TcpListener
  332.    
  333. }
  334. // namespace System.Net.Sockets

Developer Fusion