UdpClient.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. //
  2. // System.Net.Sockets.UdpClient.cs
  3. //
  4. // Author:
  5. // Gonzalo Paniagua Javier <[email protected]>
  6. //
  7. // Copyright (C) Ximian, Inc. http://www.ximian.com
  8. //
  9. using System;
  10. using System.Net;
  11. namespace System.Net.Sockets
  12. {
  13. public class UdpClient : IDisposable
  14. {
  15. private bool disposed = false;
  16. private bool active = false;
  17. private Socket socket;
  18. #region Constructors
  19. public UdpClient ()
  20. {
  21. InitSocket (null);
  22. }
  23. public UdpClient (int port)
  24. {
  25. if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
  26. throw new ArgumentOutOfRangeException ("port");
  27. IPEndPoint localEP = new IPEndPoint (IPAddress.Any, port);
  28. InitSocket (localEP);
  29. }
  30. public UdpClient (IPEndPoint localEP)
  31. {
  32. if (localEP == null)
  33. throw new ArgumentNullException ("localEP");
  34. InitSocket (localEP);
  35. }
  36. public UdpClient (string hostname, int port)
  37. {
  38. if (hostname == null)
  39. throw new ArgumentNullException ("hostname");
  40. if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
  41. throw new ArgumentOutOfRangeException ("port");
  42. InitSocket (null);
  43. Connect (hostname, port);
  44. }
  45. private void InitSocket (EndPoint localEP)
  46. {
  47. socket = new Socket (AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
  48. if (localEP != null)
  49. socket.Bind (localEP);
  50. }
  51. #endregion // Constructors
  52. #region Public methods
  53. #region Close
  54. public void Close ()
  55. {
  56. ((IDisposable) this).Dispose ();
  57. }
  58. #endregion
  59. #region Connect
  60. public void Connect (IPEndPoint endPoint)
  61. {
  62. CheckDisposed ();
  63. if (endPoint == null)
  64. throw new ArgumentNullException ("endPoint");
  65. socket.Connect (endPoint);
  66. active = true;
  67. }
  68. public void Connect (IPAddress addr, int port)
  69. {
  70. if (addr == null)
  71. throw new ArgumentNullException ("addr");
  72. if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
  73. throw new ArgumentOutOfRangeException ("port");
  74. Connect (new IPEndPoint (addr, port));
  75. }
  76. public void Connect (string hostname, int port)
  77. {
  78. if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
  79. throw new ArgumentOutOfRangeException ("port");
  80. Connect (new IPEndPoint (Dns.Resolve (hostname).AddressList [0], port));
  81. }
  82. #endregion
  83. #region Multicast methods
  84. public void DropMulticastGroup (IPAddress multicastAddr)
  85. {
  86. CheckDisposed ();
  87. if (multicastAddr == null)
  88. throw new ArgumentNullException ("multicastAddr");
  89. socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DropMembership,
  90. new MulticastOption (multicastAddr));
  91. }
  92. public void JoinMulticastGroup (IPAddress multicastAddr)
  93. {
  94. CheckDisposed ();
  95. socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.AddMembership,
  96. new MulticastOption (multicastAddr));
  97. }
  98. public void JoinMulticastGroup (IPAddress multicastAddr, int timeToLive)
  99. {
  100. CheckDisposed ();
  101. JoinMulticastGroup (multicastAddr);
  102. if (timeToLive < 0 || timeToLive > 255)
  103. throw new ArgumentOutOfRangeException ("timeToLive");
  104. socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive,
  105. timeToLive);
  106. }
  107. #endregion
  108. #region Data I/O
  109. public byte [] Receive (ref IPEndPoint remoteEP)
  110. {
  111. CheckDisposed ();
  112. // Length of the array for receiving data??
  113. byte [] recBuffer;
  114. int available = socket.Available;
  115. if (available < 512)
  116. available = 512;
  117. recBuffer = new byte [available];
  118. EndPoint endPoint = new IPEndPoint (IPAddress.Any, 0);
  119. int dataRead = socket.ReceiveFrom (recBuffer, ref endPoint);
  120. if (dataRead < recBuffer.Length)
  121. recBuffer = CutArray (recBuffer, dataRead);
  122. remoteEP = (IPEndPoint) endPoint;
  123. return recBuffer;
  124. }
  125. public int Send (byte [] dgram, int bytes)
  126. {
  127. CheckDisposed ();
  128. if (dgram == null)
  129. throw new ArgumentNullException ("dgram");
  130. if (!active)
  131. throw new InvalidOperationException ("Operation not allowed on " +
  132. "non-connected sockets.");
  133. return socket.Send (dgram, 0, bytes, SocketFlags.None);
  134. }
  135. public int Send (byte [] dgram, int bytes, IPEndPoint endPoint)
  136. {
  137. CheckDisposed ();
  138. if (dgram == null)
  139. throw new ArgumentNullException ("dgram is null");
  140. if (active) {
  141. if (endPoint != null)
  142. throw new InvalidOperationException ("Cannot send packets to an " +
  143. "arbitrary host while connected.");
  144. return socket.Send (dgram, 0, bytes, SocketFlags.None);
  145. }
  146. return socket.SendTo (dgram, 0, bytes, SocketFlags.None, endPoint);
  147. }
  148. public int Send (byte [] dgram, int bytes, string hostname, int port)
  149. {
  150. return Send (dgram, bytes,
  151. new IPEndPoint (Dns.Resolve (hostname).AddressList [0], port));
  152. }
  153. private byte [] CutArray (byte [] orig, int length)
  154. {
  155. byte [] newArray = new byte [length];
  156. Buffer.BlockCopy (orig, 0, newArray, 0, length);
  157. return newArray;
  158. }
  159. #endregion
  160. #region Properties
  161. protected bool Active {
  162. get { return active; }
  163. set { active = value; }
  164. }
  165. protected Socket Client {
  166. get { return socket; }
  167. set { socket = value; }
  168. }
  169. #endregion
  170. #region Disposing
  171. void IDisposable.Dispose ()
  172. {
  173. Dispose (true);
  174. GC.SuppressFinalize (this);
  175. }
  176. void Dispose (bool disposing)
  177. {
  178. if (disposed)
  179. return;
  180. disposed = true;
  181. if (disposing) {
  182. // release managed resources
  183. }
  184. // release unmanaged resources
  185. Socket s = socket;
  186. socket = null;
  187. if (s != null)
  188. s.Close ();
  189. }
  190. ~UdpClient ()
  191. {
  192. Dispose (false);
  193. }
  194. private void CheckDisposed ()
  195. {
  196. if (disposed)
  197. throw new ObjectDisposedException (GetType().FullName);
  198. }
  199. #endregion
  200. #endregion
  201. }
  202. }