2 // System.Net.Sockets.UdpClient.cs
\r
5 // Gonzalo Paniagua Javier <gonzalo@ximian.com>
\r
7 // Copyright (C) Ximian, Inc. http://www.ximian.com
\r
13 namespace System.Net.Sockets
\r
15 public class UdpClient : IDisposable
\r
17 private bool disposed = false;
\r
18 private bool active = false;
\r
19 private Socket socket;
\r
20 private AddressFamily family = AddressFamily.InterNetwork;
\r
22 #region Constructors
\r
23 public UdpClient () : this(AddressFamily.InterNetwork)
\r
27 public UdpClient(AddressFamily family)
\r
29 if(family != AddressFamily.InterNetwork && family != AddressFamily.InterNetwork)
\r
30 throw new ArgumentException("family");
\r
32 this.family = family;
\r
36 public UdpClient (int port)
\r
38 if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
\r
39 throw new ArgumentOutOfRangeException ("port");
\r
41 this.family = AddressFamily.InterNetwork;
\r
43 IPEndPoint localEP = new IPEndPoint (IPAddress.Any, port);
\r
44 InitSocket (localEP);
\r
47 public UdpClient (IPEndPoint localEP)
\r
49 if (localEP == null)
\r
50 throw new ArgumentNullException ("localEP");
\r
52 this.family = localEP.AddressFamily;
\r
54 InitSocket (localEP);
\r
57 public UdpClient (string hostname, int port)
\r
59 if (hostname == null)
\r
60 throw new ArgumentNullException ("hostname");
\r
62 if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
\r
63 throw new ArgumentOutOfRangeException ("port");
\r
66 Connect (hostname, port);
\r
69 private void InitSocket (EndPoint localEP)
\r
71 if(socket != null) {
\r
76 socket = new Socket (family, SocketType.Dgram, ProtocolType.Udp);
\r
78 if (localEP != null)
\r
79 socket.Bind (localEP);
\r
82 #endregion // Constructors
\r
83 #region Public methods
\r
85 public void Close ()
\r
87 ((IDisposable) this).Dispose ();
\r
91 public void Connect (IPEndPoint endPoint)
\r
94 if (endPoint == null)
\r
95 throw new ArgumentNullException ("endPoint");
\r
97 socket.Connect (endPoint);
\r
101 public void Connect (IPAddress addr, int port)
\r
104 throw new ArgumentNullException ("addr");
\r
106 if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
\r
107 throw new ArgumentOutOfRangeException ("port");
\r
109 Connect (new IPEndPoint (addr, port));
\r
112 public void Connect (string hostname, int port)
\r
114 if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
\r
115 throw new ArgumentOutOfRangeException ("port");
\r
117 IPAddress[] addresses = Dns.Resolve (hostname).AddressList;
\r
118 for(int i=0; i<addresses.Length; i++) {
\r
120 Console.WriteLine("Trying: {0}, Family: {1}", addresses[i], addresses[i].AddressFamily);
\r
122 this.family = addresses[i].AddressFamily;
\r
123 Connect (new IPEndPoint (addresses[i], port));
\r
125 Console.WriteLine("Connected: {0}, Family: {1}", addresses[i], family);
\r
128 catch(Exception e) {
\r
129 if(i == addresses.Length - 1){
\r
130 if(socket != null) {
\r
135 /// This is the last entry, re-throw the exception
\r
143 #region Multicast methods
\r
144 public void DropMulticastGroup (IPAddress multicastAddr)
\r
147 if (multicastAddr == null)
\r
148 throw new ArgumentNullException ("multicastAddr");
\r
150 if(family == AddressFamily.InterNetwork)
\r
151 socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DropMembership,
\r
152 new MulticastOption (multicastAddr));
\r
155 socket.SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DropMembership,
\r
156 new IPv6MulticastOption (multicastAddr));
\r
160 public void JoinMulticastGroup (IPAddress multicastAddr)
\r
164 if(family == AddressFamily.InterNetwork)
\r
165 socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.AddMembership,
\r
166 new MulticastOption (multicastAddr));
\r
169 socket.SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.AddMembership,
\r
170 new IPv6MulticastOption (multicastAddr));
\r
174 public void JoinMulticastGroup (IPAddress multicastAddr, int timeToLive)
\r
177 JoinMulticastGroup (multicastAddr);
\r
178 if (timeToLive < 0 || timeToLive > 255)
\r
179 throw new ArgumentOutOfRangeException ("timeToLive");
\r
181 if(family == AddressFamily.InterNetwork)
\r
182 socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive,
\r
186 socket.SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastTimeToLive,
\r
192 public byte [] Receive (ref IPEndPoint remoteEP)
\r
196 // Bug 45633: the spec states that we should block until a datagram arrives:
\r
197 // remove the 512 hardcoded value.
\r
199 // Block until we get it.
\r
200 socket.Poll (-1, SelectMode.SelectRead);
\r
203 int available = socket.Available;
\r
205 recBuffer = new byte [available];
\r
206 EndPoint endPoint = new IPEndPoint (IPAddress.Any, 0);
\r
207 int dataRead = socket.ReceiveFrom (recBuffer, ref endPoint);
\r
208 if (dataRead < recBuffer.Length)
\r
209 recBuffer = CutArray (recBuffer, dataRead);
\r
211 remoteEP = (IPEndPoint) endPoint;
\r
215 public int Send (byte [] dgram, int bytes)
\r
219 throw new ArgumentNullException ("dgram");
\r
222 throw new InvalidOperationException ("Operation not allowed on " +
\r
223 "non-connected sockets.");
\r
225 return socket.Send (dgram, 0, bytes, SocketFlags.None);
\r
228 public int Send (byte [] dgram, int bytes, IPEndPoint endPoint)
\r
232 throw new ArgumentNullException ("dgram is null");
\r
235 if (endPoint != null)
\r
236 throw new InvalidOperationException ("Cannot send packets to an " +
\r
237 "arbitrary host while connected.");
\r
239 return socket.Send (dgram, 0, bytes, SocketFlags.None);
\r
242 return socket.SendTo (dgram, 0, bytes, SocketFlags.None, endPoint);
\r
245 public int Send (byte [] dgram, int bytes, string hostname, int port)
\r
247 return Send (dgram, bytes,
\r
248 new IPEndPoint (Dns.Resolve (hostname).AddressList [0], port));
\r
251 private byte [] CutArray (byte [] orig, int length)
\r
253 byte [] newArray = new byte [length];
\r
254 Buffer.BlockCopy (orig, 0, newArray, 0, length);
\r
260 protected bool Active {
\r
261 get { return active; }
\r
262 set { active = value; }
\r
265 protected Socket Client {
\r
266 get { return socket; }
\r
267 set { socket = value; }
\r
271 void IDisposable.Dispose ()
\r
274 GC.SuppressFinalize (this);
\r
277 void Dispose (bool disposing)
\r
283 // release managed resources
\r
285 // release unmanaged resources
\r
297 private void CheckDisposed ()
\r
300 throw new ObjectDisposedException (GetType().FullName);
\r