1 // System.Net.Sockets.TcpClient.cs
4 // Phillip Pearson (pp@myelin.co.nz)
6 // Copyright (C) 2001, Phillip Pearson
7 // http://www.myelin.co.nz
10 // NB: This is untested (probably buggy) code - take care if using it
15 namespace System.Net.Sockets
18 /// A slightly more abstracted way to create an
19 /// outgoing network connections than a Socket.
21 public class TcpClient : IDisposable
25 private NetworkStream stream;
27 private Socket client;
28 private bool disposed = false;
33 /// Some code that is shared between the constructors.
35 private void Init (AddressFamily family)
39 if(client != null) {
\r
44 client = new Socket(family, SocketType.Stream, ProtocolType.Tcp);
48 /// Constructs a new TcpClient with no connection set up
52 Init(AddressFamily.InterNetwork);
53 client.Bind(new IPEndPoint(IPAddress.Any, 0));
57 public TcpClient (AddressFamily family)
59 if (family != AddressFamily.InterNetwork &&
60 family != AddressFamily.InterNetworkV6) {
61 throw new ArgumentException ("Family must be InterNetwork or InterNetworkV6", "family");
65 client.Bind (new IPEndPoint (IPAddress.Any, 0));
70 /// Constructs a new TcpClient with a specified local endpoint.
71 /// Use this if you want to have your connections originating
72 /// from a certain port, or a certain IP (on a multi homed
75 /// <param name="local_end_point">The aforementioned local endpoint</param>
76 public TcpClient (IPEndPoint local_end_point)
78 Init(local_end_point.AddressFamily);
79 client.Bind(local_end_point);
83 /// Constructs a new TcpClient and connects to a specified
84 /// host on a specified port. A quick way to set up a network
87 /// <param name="hostname">The host to connect to, e.g.
88 /// 192.168.0.201 or www.myelin.co.nz</param>
89 /// <param name="port">The port to connect to, e.g. 80 for HTTP</param>
90 public TcpClient (string hostname, int port)
92 Connect(hostname, port);
96 /// A flag that is 'true' if the TcpClient has an active connection
100 get { return active; }
101 set { active = value; }
105 /// The socket that all network comms passes through
107 protected Socket Client
109 get { return client; }
117 /// Internal function to allow TcpListener.AcceptTcpClient
118 /// to work (it needs to be able to set protected property
121 /// <param name="s"></param>
122 internal void SetTcpClient (Socket s)
128 /// If set, the socket will remain open after it has been
129 /// instructed to close, in order to send data that remains
132 public LingerOption LingerState
135 return (LingerOption)client.GetSocketOption(
136 SocketOptionLevel.Socket,
137 SocketOptionName.Linger);
140 client.SetSocketOption(
141 SocketOptionLevel.Socket,
142 SocketOptionName.Linger, value);
147 /// <p>If set, outbound data will be sent at once rather than collected
148 /// until enough is available to fill a packet.</p>
150 /// <p>This is the TCP_NODELAY sockopt from BSD sockets and WinSock.
151 /// For more information, look up the Nagle algorithm.</p>
156 return (bool)client.GetSocketOption(
157 SocketOptionLevel.Tcp,
158 SocketOptionName.NoDelay);
161 client.SetSocketOption(
162 SocketOptionLevel.Tcp,
163 SocketOptionName.NoDelay, value);
168 /// How big the receive buffer is (from the connection socket)
170 public int ReceiveBufferSize
173 return (int)client.GetSocketOption(
174 SocketOptionLevel.Socket,
175 SocketOptionName.ReceiveBuffer);
178 client.SetSocketOption(
179 SocketOptionLevel.Socket,
180 SocketOptionName.ReceiveBuffer, value);
185 /// How long before the socket will time out on a
188 public int ReceiveTimeout
191 return (int)client.GetSocketOption(
192 SocketOptionLevel.Socket,
193 SocketOptionName.ReceiveTimeout);
196 client.SetSocketOption(
197 SocketOptionLevel.Socket,
198 SocketOptionName.ReceiveTimeout, value);
203 /// How big the send buffer is (from the connection socket)
205 public int SendBufferSize
208 return (int)client.GetSocketOption(
209 SocketOptionLevel.Socket,
210 SocketOptionName.SendBuffer);
213 client.SetSocketOption(
214 SocketOptionLevel.Socket,
215 SocketOptionName.SendBuffer, value);
220 /// How long before the socket will time out on a
223 public int SendTimeout
226 return (int)client.GetSocketOption(
227 SocketOptionLevel.Socket,
228 SocketOptionName.SendTimeout);
231 client.SetSocketOption(
232 SocketOptionLevel.Socket,
233 SocketOptionName.SendTimeout, value);
241 /// Closes the socket and disposes of all managed resources.
243 /// Throws SocketException if something goes wrong while
244 /// closing the socket.
248 ((IDisposable) this).Dispose ();
252 /// Connects to a specified remote endpoint
254 /// Throws SocketException if something goes wrong while
257 /// <param name="remote_end_point">The aforementioned endpoint</param>
258 public void Connect (IPEndPoint remote_end_point)
261 client.Connect(remote_end_point);
262 stream = new NetworkStream(client, true);
270 /// Connects to an IP address on a port
272 /// Throws SocketException if something goes wrong while
275 /// <param name="address">The IP address (get it from Dns.GetHostByName)</param>
276 /// <param name="port">The port to connect to, e.g. 80 for HTTP</param>
277 public void Connect (IPAddress address, int port)
279 Connect(new IPEndPoint(address, port));
283 /// Resolves a fully qualified domain name to an IP address
284 /// and connects to it on a specified port
286 /// Throws SocketException if something goes wrong while
289 /// <param name="hostname">The hostname, e.g. www.myelin.co.nz</param>
290 /// <param name="port">The port, e.g. 80 for HTTP</param>
292 public void Connect (string hostname, int port)
296 IPHostEntry host = Dns.GetHostByName(hostname);
298 for(int i=0; i<host.AddressList.Length; i++)
301 Init(host.AddressList[i].AddressFamily);
303 if(host.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
304 client.Bind(new IPEndPoint(IPAddress.Any, 0));
306 else if(host.AddressList[i].AddressFamily == AddressFamily.InterNetworkV6)
307 client.Bind(new IPEndPoint(IPAddress.IPv6Any, 0));
310 Connect(new IPEndPoint(host.AddressList[i], port));
313 catch(Exception e) {
\r
314 if(client != null) {
\r
319 /// This is the last known address, re-throw the exception
\r
320 if(i == host.AddressList.Length-1)
\r
327 /// Gets rid of all managed resources
329 void IDisposable.Dispose ()
332 GC.SuppressFinalize (this);
336 /// Gets rid of all unmanaged resources
338 /// <param name="disposing">If this is true, it gets rid of all
339 /// managed resources as well</param>
340 protected virtual void Dispose (bool disposing)
347 // release managed resources
348 NetworkStream s = stream;
351 // This closes the socket as well, as the NetworkStream
356 } else if (client != null){
364 /// Destructor - just calls Dispose()
371 /// <returns>A NetworkStream object connected to the
372 /// connection socket</returns>
373 public NetworkStream GetStream()
378 stream = new NetworkStream (client, true);
382 finally { CheckDisposed (); }
385 private void CheckDisposed ()
388 throw new ObjectDisposedException (GetType().FullName);