* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System / System.Net.Sockets / TcpListener.cs
1 // System.Net.Sockets.TcpListener.cs
2 //
3 // Authors:
4 //    Phillip Pearson (pp@myelin.co.nz)
5 //    Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //        Patrik Torstensson
7 //
8 // Copyright (C) 2001, Phillip Pearson
9 //    http://www.myelin.co.nz
10 //
11 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
12 // (c) 2004 Novell, Inc.
13 //
14
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35
36 using System;
37 using System.Net;
38
39 namespace System.Net.Sockets
40 {
41         /// <remarks>
42         /// A slightly more abstracted way to listen for incoming
43         /// network connections than a Socket.
44         /// </remarks>
45         public class TcpListener
46         {
47                 // private data
48                 
49                 bool active;
50                 Socket server;
51                 EndPoint savedEP;
52                 
53                 // constructor
54
55                 /// <summary>
56                 /// Some code that is shared between the constructors.
57                 /// </summary>
58                 private void Init (AddressFamily family, EndPoint ep)
59                 {
60                         active = false;
61                         server = new Socket(family, SocketType.Stream, ProtocolType.Tcp);
62                         savedEP = ep;
63                 }
64                 
65                 /// <summary>
66                 /// Constructs a new TcpListener to listen on a specified port
67                 /// </summary>
68                 /// <param name="port">The port to listen on, e.g. 80 if you 
69                 /// are a web server</param>
70 #if NET_1_1
71                 [Obsolete ("Use TcpListener (IPAddress address, int port) instead")]
72 #endif
73                 public TcpListener (int port)
74                 {
75                         if (port < 0 || port > 65535)
76                                 throw new ArgumentOutOfRangeException ("port");
77
78                         Init (AddressFamily.InterNetwork, new IPEndPoint (IPAddress.Any, port));
79                 }
80
81                 /// <summary>
82                 /// Constructs a new TcpListener with a specified local endpoint
83                 /// </summary>
84                 /// <param name="local_end_point">The endpoint</param>
85                 public TcpListener (IPEndPoint local_end_point)
86                 {
87                         if (local_end_point == null)
88                                 throw new ArgumentNullException ("local_end_point");
89
90                         Init (local_end_point.AddressFamily, local_end_point);
91                 }
92                 
93                 /// <summary>
94                 /// Constructs a new TcpListener, listening on a specified port
95                 /// and IP (for use on a multi-homed machine)
96                 /// </summary>
97                 /// <param name="listen_ip">The IP to listen on</param>
98                 /// <param name="port">The port to listen on</param>
99                 public TcpListener (IPAddress listen_ip, int port)
100                 {
101                         if (listen_ip == null)
102                                 throw new ArgumentNullException ("listen_ip");
103
104                         if (port < 0 || port > 65535)
105                                 throw new ArgumentOutOfRangeException ("port");
106
107                         Init (listen_ip.AddressFamily, new IPEndPoint(listen_ip, port));
108                 }
109
110
111                 // properties
112
113                 /// <summary>
114                 /// A flag that is 'true' if the TcpListener is listening,
115                 /// or 'false' if it is not listening
116                 /// </summary>
117                 protected bool Active
118                 {
119                         get { return active; }
120                 }
121
122                 /// <summary>
123                 /// The local end point
124                 /// </summary>
125                 public EndPoint LocalEndpoint
126                 {
127                         get { 
128                                 if (active)
129                                         return server.LocalEndPoint;
130
131                                 return savedEP; 
132                         }
133                 }
134                 
135                 /// <summary>
136                 /// The listening socket
137                 /// </summary>
138                 protected Socket Server
139                 {
140                         get { return server; }
141                 }
142                 
143                 
144                 // methods
145
146                 /// <summary>
147                 /// Accepts a pending connection
148                 /// </summary>
149                 /// <returns>A Socket object for the new connection</returns>
150                 public Socket AcceptSocket ()
151                 {
152                         if (!active)
153                                 throw new InvalidOperationException ("Socket is not listening");
154
155                         return server.Accept();
156                 }
157                 
158                 /// <summary>
159                 /// Accepts a pending connection
160                 /// </summary>
161                 /// <returns>A TcpClient
162                 /// object made from the new socket.</returns>
163                 public TcpClient AcceptTcpClient ()
164                 {
165                         if (!active)
166                                 throw new InvalidOperationException ("Socket is not listening");
167
168                         Socket clientSocket = server.Accept ();
169
170                         TcpClient client = new TcpClient();
171                         // use internal method SetTcpClient to make a
172                         // client with the specified socket
173                         client.SetTcpClient (clientSocket);
174                         
175                         return client;
176                 }
177                 
178                 /// <summary>
179                 /// Destructor - stops the listener listening
180                 /// </summary>
181                 ~TcpListener ()
182                 {
183                         if (active)
184                                 Stop();
185                 }
186         
187                 /// <returns>
188                 /// Returns 'true' if there is a connection waiting to be accepted
189                 /// with AcceptSocket() or AcceptTcpClient().
190                 /// </returns>
191                 public bool Pending ()
192                 {
193                         if (!active)
194                                 throw new InvalidOperationException ("Socket is not listening");
195
196                         return server.Poll(0, SelectMode.SelectRead);
197                 }
198                 
199                 /// <summary>
200                 /// Tells the TcpListener to start listening.
201                 /// </summary>
202                 public void Start ()
203                 {
204                         if (active)
205                                 return;
206
207                         if (server == null)
208                                 throw new InvalidOperationException("Invalid server socket");
209
210                         server.Bind (savedEP);
211                         
212                         // MS: sets Listen to Int32.MaxValue
213                         server.Listen(5);       
214                         // According to the man page some BSD and BSD-derived
215                         // systems limit the backlog to 5.  This should really be
216                         // configurable though
217
218                         active = true;
219                 }
220                 
221                 /// <summary>
222                 /// Tells the TcpListener to stop listening and dispose
223                 /// of all managed resources.
224                 /// </summary>
225                 public void Stop ()
226                 {
227                         if (active) \r
228                         {\r
229                                 server.Close ();
230                                 server = null;
231                         }
232
233                         Init (AddressFamily.InterNetwork, savedEP);
234                 }
235
236         }
237 }