Welcome to mirror list, hosted at ThFree Co, Russian Federation.

TcpClient.cs « System.Net.Sockets « System « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a6700373cfa17111e532e3656f575035efdfea80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
// System.Net.Sockets.TcpClient.cs
//
// Author:
//    Phillip Pearson (pp@myelin.co.nz)
//
// Copyright (C) 2001, Phillip Pearson
//    http://www.myelin.co.nz
//

// NB: This is untested (probably buggy) code - take care if using it

using System;
using System.Net;

namespace System.Net.Sockets
{
	/// <remarks>
	/// A slightly more abstracted way to create an
	/// outgoing network connections than a Socket.
	/// </remarks>
	public class TcpClient : IDisposable
	{
		// private data
		
		private NetworkStream stream;
		private bool active;
		private Socket client;
		private bool disposed = false;
		
		// constructor

		/// <summary>
		/// Some code that is shared between the constructors.
		/// </summary>
		private void Init ()
		{
			active = false;
			client = new Socket(AddressFamily.InterNetwork,
				SocketType.Stream, ProtocolType.Tcp);
		}

		/// <summary>
		/// Constructs a new TcpClient with no connection set up
		/// </summary>
		public TcpClient ()
		{
			Init();
			client.Bind(new IPEndPoint(IPAddress.Any, 0));
		}
	
		/// <summary>
		/// Constructs a new TcpClient with a specified local endpoint.
		/// Use this if you want to have your connections originating
		/// from a certain port, or a certain IP (on a multi homed
		/// system).
		/// </summary>
		/// <param name="local_end_point">The aforementioned local endpoint</param>
		public TcpClient (IPEndPoint local_end_point)
		{
			Init();
			client.Bind(local_end_point);
		}
		
		/// <summary>
		/// Constructs a new TcpClient and connects to a specified
		/// host on a specified port.  A quick way to set up a network
		/// connection.
		/// </summary>
		/// <param name="hostname">The host to connect to, e.g.
		/// 192.168.0.201 or www.myelin.co.nz</param>
		/// <param name="port">The port to connect to, e.g. 80 for HTTP</param>
		public TcpClient (string hostname, int port)
		{
			Init();
			client.Bind(new IPEndPoint(IPAddress.Any, 0));
			Connect(hostname, port);
		}
				
		/// <summary>
		/// A flag that is 'true' if the TcpClient has an active connection
		/// </summary>
		protected bool Active
		{
			get { return active; }
			set { active = value; }
		}
		
		/// <summary>
		/// The socket that all network comms passes through
		/// </summary>
		protected Socket Client
		{
			get { return client; }
			set { client = value; }
		}

		/// <summary>
		/// Internal function to allow TcpListener.AcceptTcpClient
		/// to work (it needs to be able to set protected property
		/// 'Client')
		/// </summary>
		/// <param name="s"></param>
		internal void SetTcpClient (Socket s) 
		{
			client = s;
			stream = new NetworkStream (client, true);
		}
		
		/// <summary>
		/// If set, the socket will remain open after it has been
		/// instructed to close, in order to send data that remains
		/// in the buffer.
		/// </summary>
		public LingerOption LingerState
		{
			get {
				return (LingerOption)client.GetSocketOption(
					SocketOptionLevel.Socket,
					SocketOptionName.Linger);
			}
			set {
				client.SetSocketOption(
					SocketOptionLevel.Socket,
					SocketOptionName.Linger, value);
			}
		}
				
		/// <summary>
		/// <p>If set, outbound data will be sent at once rather than collected
		/// until enough is available to fill a packet.</p>
		/// 
		/// <p>This is the TCP_NODELAY sockopt from BSD sockets and WinSock.
		/// For more information, look up the Nagle algorithm.</p>
		/// </summary>
		public bool NoDelay
		{
			get {
				return (bool)client.GetSocketOption(
					SocketOptionLevel.Socket,
					SocketOptionName.NoDelay);
			}
			set {
				client.SetSocketOption(
					SocketOptionLevel.Socket,
					SocketOptionName.NoDelay, value);
			}
		}
				
		/// <summary>
		/// How big the receive buffer is (from the connection socket)
		/// </summary>
		public int ReceiveBufferSize
		{
			get {
				return (int)client.GetSocketOption(
					SocketOptionLevel.Socket,
					SocketOptionName.ReceiveBuffer);
			}
			set {
				client.SetSocketOption(
					SocketOptionLevel.Socket,
					SocketOptionName.ReceiveBuffer, value);
			}
		}
			
		/// <summary>
		/// How long before the socket will time out on a 
		/// Receive() call
		/// </summary>
		public int ReceiveTimeout
		{
			get {
				return (int)client.GetSocketOption(
					SocketOptionLevel.Socket,
					SocketOptionName.ReceiveTimeout);
			}
			set {
				client.SetSocketOption(
					SocketOptionLevel.Socket,
					SocketOptionName.ReceiveTimeout, value);
			}
		}
		
		/// <summary>
		/// How big the send buffer is (from the connection socket)
		/// </summary>
		public int SendBufferSize
		{
			get {
				return (int)client.GetSocketOption(
					SocketOptionLevel.Socket,
					SocketOptionName.SendBuffer);
			}
			set {
				client.SetSocketOption(
					SocketOptionLevel.Socket,
					SocketOptionName.SendBuffer, value);
			}
		}
		
		/// <summary>
		/// How long before the socket will time out on a
		/// Send() call
		/// </summary>
		public int SendTimeout
		{
			get {
				return (int)client.GetSocketOption(
					SocketOptionLevel.Socket,
					SocketOptionName.SendTimeout);
			}
			set {
				client.SetSocketOption(
					SocketOptionLevel.Socket,
					SocketOptionName.SendTimeout, value);
			}
		}
		
		
		// methods
		
		/// <summary>
		/// Closes the socket and disposes of all managed resources.
		/// 
		/// Throws SocketException if something goes wrong while
		/// closing the socket.
		/// </summary>
		public void Close ()
		{
			((IDisposable) this).Dispose ();
		}
		
		/// <summary>
		/// Connects to a specified remote endpoint
		/// 
		/// Throws SocketException if something goes wrong while
		/// connecting.
		/// </summary>
		/// <param name="remote_end_point">The aforementioned endpoint</param>
		public void Connect (IPEndPoint remote_end_point)
		{
			try {
				client.Connect(remote_end_point);
				stream = new NetworkStream(client, true);
				active = true;
			} finally {
				CheckDisposed ();
			}
		}
		
		/// <summary>
		/// Connects to an IP address on a port
		/// 
		/// Throws SocketException if something goes wrong while
		/// connecting.
		/// </summary>
		/// <param name="address">The IP address (get it from Dns.GetHostByName)</param>
		/// <param name="port">The port to connect to, e.g. 80 for HTTP</param>
		public void Connect (IPAddress address, int port)
		{
			Connect(new IPEndPoint(address, port));
		}
		
		/// <summary>
		/// Resolves a fully qualified domain name to an IP address
		/// and connects to it on a specified port
		/// 
		/// Throws SocketException if something goes wrong while
		/// connecting.
		/// </summary>
		/// <param name="hostname">The hostname, e.g. www.myelin.co.nz</param>
		/// <param name="port">The port, e.g. 80 for HTTP</param>
		[MonoTODO]
		public void Connect (string hostname, int port)
		{
			CheckDisposed ();
			IPHostEntry host = Dns.GetHostByName(hostname);
			/* TODO: This will connect to the first IP address returned
			from GetHostByName.  Is that right? */
			Connect(new IPEndPoint(host.AddressList[0], port));
		}
		
		/// <summary>
		/// Gets rid of all managed resources
		/// </summary>
		void IDisposable.Dispose ()
		{
			Dispose (true);
			GC.SuppressFinalize (this);
		}

		/// <summary>
		/// Gets rid of all unmanaged resources
		/// </summary>
		/// <param name="disposing">If this is true, it gets rid of all
		/// managed resources as well</param>
		protected virtual void Dispose (bool disposing)
		{
			if (disposed)
				return;
			disposed = true;
				
			// release unmanaged resources
			NetworkStream s = stream;
			stream = null;
			if (s != null) {
				// This closes the socket as well, as the NetworkStream
				// owns the socket.
				s.Close();
				active = false;
				s = null;
			}
			client = null;
		}
		
		/// <summary>
		/// Destructor - just calls Dispose()
		/// </summary>
		~TcpClient ()
		{
			Dispose (false);
		}
		
		/// <returns>A NetworkStream object connected to the
		/// connection socket</returns>
		public NetworkStream GetStream()
		{
			try { return stream; }
			finally { CheckDisposed (); }
		}
		
		private void CheckDisposed ()
		{
			if (disposed)
				throw new ObjectDisposedException (GetType().FullName);
		}		
	}
}