PageRenderTime 46ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/System/System.Net.Sockets/Socket.cs

https://bitbucket.org/danipen/mono
C# | 2109 lines | 1555 code | 410 blank | 144 comment | 593 complexity | 87ca90f5f76a7bee9778de59b6da23bd MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. // System.Net.Sockets.Socket.cs
  2. //
  3. // Authors:
  4. // Phillip Pearson (pp@myelin.co.nz)
  5. // Dick Porter <dick@ximian.com>
  6. // Gonzalo Paniagua Javier (gonzalo@ximian.com)
  7. // Sridhar Kulkarni (sridharkulkarni@gmail.com)
  8. // Brian Nickel (brian.nickel@gmail.com)
  9. //
  10. // Copyright (C) 2001, 2002 Phillip Pearson and Ximian, Inc.
  11. // http://www.myelin.co.nz
  12. // (c) 2004-2011 Novell, Inc. (http://www.novell.com)
  13. //
  14. //
  15. // Permission is hereby granted, free of charge, to any person obtaining
  16. // a copy of this software and associated documentation files (the
  17. // "Software"), to deal in the Software without restriction, including
  18. // without limitation the rights to use, copy, modify, merge, publish,
  19. // distribute, sublicense, and/or sell copies of the Software, and to
  20. // permit persons to whom the Software is furnished to do so, subject to
  21. // the following conditions:
  22. //
  23. // The above copyright notice and this permission notice shall be
  24. // included in all copies or substantial portions of the Software.
  25. //
  26. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  27. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  28. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  29. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  30. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  31. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  32. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  33. //
  34. using System;
  35. using System.Net;
  36. using System.Collections;
  37. using System.Collections.Generic;
  38. using System.Runtime.CompilerServices;
  39. using System.Runtime.InteropServices;
  40. using System.Threading;
  41. using System.Reflection;
  42. using System.IO;
  43. using System.Net.Configuration;
  44. using System.Text;
  45. using System.Timers;
  46. using System.Net.NetworkInformation;
  47. namespace System.Net.Sockets
  48. {
  49. public partial class Socket : IDisposable
  50. {
  51. private bool islistening;
  52. private bool useoverlappedIO;
  53. private const int SOCKET_CLOSED = 10004;
  54. static void AddSockets (List<Socket> sockets, IList list, string name)
  55. {
  56. if (list != null) {
  57. foreach (Socket sock in list) {
  58. if (sock == null) // MS throws a NullRef
  59. throw new ArgumentNullException ("name", "Contains a null element");
  60. sockets.Add (sock);
  61. }
  62. }
  63. sockets.Add (null);
  64. }
  65. #if !TARGET_JVM
  66. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  67. private extern static void Select_internal (ref Socket [] sockets,
  68. int microSeconds,
  69. out int error);
  70. #endif
  71. public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
  72. {
  73. var list = new List<Socket> ();
  74. AddSockets (list, checkRead, "checkRead");
  75. AddSockets (list, checkWrite, "checkWrite");
  76. AddSockets (list, checkError, "checkError");
  77. if (list.Count == 3) {
  78. throw new ArgumentNullException ("checkRead, checkWrite, checkError",
  79. "All the lists are null or empty.");
  80. }
  81. int error;
  82. /*
  83. * The 'sockets' array contains: READ socket 0-n, null,
  84. * WRITE socket 0-n, null,
  85. * ERROR socket 0-n, null
  86. */
  87. Socket [] sockets = list.ToArray ();
  88. Select_internal (ref sockets, microSeconds, out error);
  89. if (error != 0)
  90. throw new SocketException (error);
  91. if (sockets == null) {
  92. if (checkRead != null)
  93. checkRead.Clear ();
  94. if (checkWrite != null)
  95. checkWrite.Clear ();
  96. if (checkError != null)
  97. checkError.Clear ();
  98. return;
  99. }
  100. int mode = 0;
  101. int count = sockets.Length;
  102. IList currentList = checkRead;
  103. int currentIdx = 0;
  104. for (int i = 0; i < count; i++) {
  105. Socket sock = sockets [i];
  106. if (sock == null) { // separator
  107. if (currentList != null) {
  108. // Remove non-signaled sockets after the current one
  109. int to_remove = currentList.Count - currentIdx;
  110. for (int k = 0; k < to_remove; k++)
  111. currentList.RemoveAt (currentIdx);
  112. }
  113. currentList = (mode == 0) ? checkWrite : checkError;
  114. currentIdx = 0;
  115. mode++;
  116. continue;
  117. }
  118. if (mode == 1 && currentList == checkWrite && !sock.connected) {
  119. if ((int) sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0)
  120. sock.connected = true;
  121. }
  122. // Remove non-signaled sockets before the current one
  123. //int max = currentList.Count;
  124. while (((Socket) currentList [currentIdx]) != sock) {
  125. currentList.RemoveAt (currentIdx);
  126. }
  127. currentIdx++;
  128. }
  129. }
  130. // private constructor used by Accept, which already
  131. // has a socket handle to use
  132. internal Socket(AddressFamily family, SocketType type,
  133. ProtocolType proto, IntPtr sock)
  134. {
  135. address_family=family;
  136. socket_type=type;
  137. protocol_type=proto;
  138. socket=sock;
  139. connected=true;
  140. }
  141. private void SocketDefaults ()
  142. {
  143. try {
  144. if (address_family == AddressFamily.InterNetwork /* Need to test IPv6 further ||
  145. address_family == AddressFamily.InterNetworkV6 */) {
  146. /* This is the default, but it
  147. * probably has nasty side
  148. * effects on Linux, as the
  149. * socket option is kludged by
  150. * turning on or off PMTU
  151. * discovery...
  152. */
  153. this.DontFragment = false;
  154. }
  155. //
  156. // Microsoft sets these to 8192, but we are going to keep them
  157. // both to the OS defaults as these have a big performance impact.
  158. // on WebClient performance.
  159. //
  160. //this.ReceiveBufferSize = 8192;
  161. //this.SendBufferSize = 8192;
  162. } catch (SocketException) {
  163. }
  164. }
  165. #if !MOBILE
  166. public Socket (SocketInformation socketInformation)
  167. {
  168. var options = socketInformation.Options;
  169. islistening = (options & SocketInformationOptions.Listening) != 0;
  170. connected = (options & SocketInformationOptions.Connected) != 0;
  171. blocking = (options & SocketInformationOptions.NonBlocking) == 0;
  172. useoverlappedIO = (options & SocketInformationOptions.UseOnlyOverlappedIO) != 0;
  173. var result = Mono.DataConverter.Unpack ("iiiil", socketInformation.ProtocolInformation, 0);
  174. address_family = (AddressFamily) (int) result [0];
  175. socket_type = (SocketType) (int) result [1];
  176. protocol_type = (ProtocolType) (int) result [2];
  177. isbound = (ProtocolType) (int) result [3] != 0;
  178. socket = (IntPtr) (long) result [4];
  179. SocketDefaults ();
  180. }
  181. #endif
  182. #if !TARGET_JVM
  183. // Returns the amount of data waiting to be read on socket
  184. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  185. private extern static int Available_internal(IntPtr socket, out int error);
  186. #endif
  187. public int Available {
  188. get {
  189. if (disposed && closed)
  190. throw new ObjectDisposedException (GetType ().ToString ());
  191. int ret, error;
  192. ret = Available_internal(socket, out error);
  193. if (error != 0)
  194. throw new SocketException (error);
  195. return(ret);
  196. }
  197. }
  198. public bool DontFragment {
  199. get {
  200. if (disposed && closed) {
  201. throw new ObjectDisposedException (GetType ().ToString ());
  202. }
  203. bool dontfragment;
  204. if (address_family == AddressFamily.InterNetwork) {
  205. dontfragment = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment)) != 0;
  206. } else if (address_family == AddressFamily.InterNetworkV6) {
  207. dontfragment = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment)) != 0;
  208. } else {
  209. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  210. }
  211. return(dontfragment);
  212. }
  213. set {
  214. if (disposed && closed) {
  215. throw new ObjectDisposedException (GetType ().ToString ());
  216. }
  217. if (address_family == AddressFamily.InterNetwork) {
  218. SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment, value?1:0);
  219. } else if (address_family == AddressFamily.InterNetworkV6) {
  220. SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment, value?1:0);
  221. } else {
  222. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  223. }
  224. }
  225. }
  226. public bool EnableBroadcast {
  227. get {
  228. if (disposed && closed) {
  229. throw new ObjectDisposedException (GetType ().ToString ());
  230. }
  231. if (protocol_type != ProtocolType.Udp) {
  232. throw new SocketException ((int)SocketError.ProtocolOption);
  233. }
  234. return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast)) != 0);
  235. }
  236. set {
  237. if (disposed && closed) {
  238. throw new ObjectDisposedException (GetType ().ToString ());
  239. }
  240. if (protocol_type != ProtocolType.Udp) {
  241. throw new SocketException ((int)SocketError.ProtocolOption);
  242. }
  243. SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast, value?1:0);
  244. }
  245. }
  246. public bool ExclusiveAddressUse {
  247. get {
  248. if (disposed && closed) {
  249. throw new ObjectDisposedException (GetType ().ToString ());
  250. }
  251. return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse)) != 0);
  252. }
  253. set {
  254. if (disposed && closed) {
  255. throw new ObjectDisposedException (GetType ().ToString ());
  256. }
  257. if (isbound) {
  258. throw new InvalidOperationException ("Bind has already been called for this socket");
  259. }
  260. SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, value?1:0);
  261. }
  262. }
  263. public bool IsBound {
  264. get {
  265. return(isbound);
  266. }
  267. }
  268. public LingerOption LingerState {
  269. get {
  270. if (disposed && closed) {
  271. throw new ObjectDisposedException (GetType ().ToString ());
  272. }
  273. return((LingerOption)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Linger));
  274. }
  275. set {
  276. if (disposed && closed) {
  277. throw new ObjectDisposedException (GetType ().ToString ());
  278. }
  279. SetSocketOption (SocketOptionLevel.Socket,
  280. SocketOptionName.Linger,
  281. value);
  282. }
  283. }
  284. public bool MulticastLoopback {
  285. get {
  286. if (disposed && closed) {
  287. throw new ObjectDisposedException (GetType ().ToString ());
  288. }
  289. /* Even though this option can be set
  290. * for TCP sockets on Linux, throw
  291. * this exception anyway to be
  292. * compatible (the MSDN docs say
  293. * "Setting this property on a
  294. * Transmission Control Protocol (TCP)
  295. * socket will have no effect." but
  296. * the MS runtime throws the
  297. * exception...)
  298. */
  299. if (protocol_type == ProtocolType.Tcp) {
  300. throw new SocketException ((int)SocketError.ProtocolOption);
  301. }
  302. bool multicastloopback;
  303. if (address_family == AddressFamily.InterNetwork) {
  304. multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback)) != 0;
  305. } else if (address_family == AddressFamily.InterNetworkV6) {
  306. multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback)) != 0;
  307. } else {
  308. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  309. }
  310. return(multicastloopback);
  311. }
  312. set {
  313. if (disposed && closed) {
  314. throw new ObjectDisposedException (GetType ().ToString ());
  315. }
  316. /* Even though this option can be set
  317. * for TCP sockets on Linux, throw
  318. * this exception anyway to be
  319. * compatible (the MSDN docs say
  320. * "Setting this property on a
  321. * Transmission Control Protocol (TCP)
  322. * socket will have no effect." but
  323. * the MS runtime throws the
  324. * exception...)
  325. */
  326. if (protocol_type == ProtocolType.Tcp) {
  327. throw new SocketException ((int)SocketError.ProtocolOption);
  328. }
  329. if (address_family == AddressFamily.InterNetwork) {
  330. SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, value?1:0);
  331. } else if (address_family == AddressFamily.InterNetworkV6) {
  332. SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback, value?1:0);
  333. } else {
  334. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  335. }
  336. }
  337. }
  338. [MonoTODO ("This doesn't do anything on Mono yet")]
  339. public bool UseOnlyOverlappedIO {
  340. get {
  341. return(useoverlappedIO);
  342. }
  343. set {
  344. useoverlappedIO = value;
  345. }
  346. }
  347. public IntPtr Handle {
  348. get {
  349. return(socket);
  350. }
  351. }
  352. #if !TARGET_JVM
  353. // Returns the local endpoint details in addr and port
  354. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  355. private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, int family, out int error);
  356. #endif
  357. // Wish: support non-IP endpoints.
  358. public EndPoint LocalEndPoint {
  359. get {
  360. if (disposed && closed)
  361. throw new ObjectDisposedException (GetType ().ToString ());
  362. /*
  363. * If the seed EndPoint is null, Connect, Bind,
  364. * etc has not yet been called. MS returns null
  365. * in this case.
  366. */
  367. if (seed_endpoint == null)
  368. return null;
  369. SocketAddress sa;
  370. int error;
  371. sa=LocalEndPoint_internal(socket, (int) address_family, out error);
  372. if (error != 0)
  373. throw new SocketException (error);
  374. return seed_endpoint.Create (sa);
  375. }
  376. }
  377. public SocketType SocketType {
  378. get {
  379. return(socket_type);
  380. }
  381. }
  382. public int SendTimeout {
  383. get {
  384. if (disposed && closed)
  385. throw new ObjectDisposedException (GetType ().ToString ());
  386. return (int)GetSocketOption(
  387. SocketOptionLevel.Socket,
  388. SocketOptionName.SendTimeout);
  389. }
  390. set {
  391. if (disposed && closed)
  392. throw new ObjectDisposedException (GetType ().ToString ());
  393. if (value < -1)
  394. throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
  395. /* According to the MSDN docs we
  396. * should adjust values between 1 and
  397. * 499 to 500, but the MS runtime
  398. * doesn't do this.
  399. */
  400. if (value == -1)
  401. value = 0;
  402. SetSocketOption(
  403. SocketOptionLevel.Socket,
  404. SocketOptionName.SendTimeout, value);
  405. }
  406. }
  407. public int ReceiveTimeout {
  408. get {
  409. if (disposed && closed)
  410. throw new ObjectDisposedException (GetType ().ToString ());
  411. return (int)GetSocketOption(
  412. SocketOptionLevel.Socket,
  413. SocketOptionName.ReceiveTimeout);
  414. }
  415. set {
  416. if (disposed && closed)
  417. throw new ObjectDisposedException (GetType ().ToString ());
  418. if (value < -1)
  419. throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
  420. if (value == -1) {
  421. value = 0;
  422. }
  423. SetSocketOption(
  424. SocketOptionLevel.Socket,
  425. SocketOptionName.ReceiveTimeout, value);
  426. }
  427. }
  428. public bool AcceptAsync (SocketAsyncEventArgs e)
  429. {
  430. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  431. if (disposed && closed)
  432. throw new ObjectDisposedException (GetType ().ToString ());
  433. if (!IsBound)
  434. throw new InvalidOperationException ("You must call the Bind method before performing this operation.");
  435. if (!islistening)
  436. throw new InvalidOperationException ("You must call the Listen method before performing this operation.");
  437. if (e.BufferList != null)
  438. throw new ArgumentException ("Multiple buffers cannot be used with this method.");
  439. if (e.Count < 0)
  440. throw new ArgumentOutOfRangeException ("e.Count");
  441. Socket acceptSocket = e.AcceptSocket;
  442. if (acceptSocket != null) {
  443. if (acceptSocket.IsBound || acceptSocket.Connected)
  444. throw new InvalidOperationException ("AcceptSocket: The socket must not be bound or connected.");
  445. }
  446. e.curSocket = this;
  447. Worker w = e.Worker;
  448. w.Init (this, e, SocketOperation.Accept);
  449. int count;
  450. lock (readQ) {
  451. readQ.Enqueue (e.Worker);
  452. count = readQ.Count;
  453. }
  454. if (count == 1)
  455. socket_pool_queue (Worker.Dispatcher, w.result);
  456. return true;
  457. }
  458. // Creates a new system socket, returning the handle
  459. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  460. private extern static IntPtr Accept_internal(IntPtr sock, out int error, bool blocking);
  461. public Socket Accept() {
  462. if (disposed && closed)
  463. throw new ObjectDisposedException (GetType ().ToString ());
  464. int error = 0;
  465. IntPtr sock = (IntPtr) (-1);
  466. try {
  467. RegisterForBlockingSyscall ();
  468. sock = Accept_internal(socket, out error, blocking);
  469. } finally {
  470. UnRegisterForBlockingSyscall ();
  471. }
  472. if (error != 0) {
  473. if (closed)
  474. error = SOCKET_CLOSED;
  475. throw new SocketException(error);
  476. }
  477. Socket accepted = new Socket(this.AddressFamily, this.SocketType,
  478. this.ProtocolType, sock);
  479. accepted.seed_endpoint = this.seed_endpoint;
  480. accepted.Blocking = this.Blocking;
  481. return(accepted);
  482. }
  483. internal void Accept (Socket acceptSocket)
  484. {
  485. if (disposed && closed)
  486. throw new ObjectDisposedException (GetType ().ToString ());
  487. int error = 0;
  488. IntPtr sock = (IntPtr)(-1);
  489. try {
  490. RegisterForBlockingSyscall ();
  491. sock = Accept_internal (socket, out error, blocking);
  492. } finally {
  493. UnRegisterForBlockingSyscall ();
  494. }
  495. if (error != 0) {
  496. if (closed)
  497. error = SOCKET_CLOSED;
  498. throw new SocketException (error);
  499. }
  500. acceptSocket.address_family = this.AddressFamily;
  501. acceptSocket.socket_type = this.SocketType;
  502. acceptSocket.protocol_type = this.ProtocolType;
  503. acceptSocket.socket = sock;
  504. acceptSocket.connected = true;
  505. acceptSocket.seed_endpoint = this.seed_endpoint;
  506. acceptSocket.Blocking = this.Blocking;
  507. /* FIXME: figure out what if anything else
  508. * needs to be reset
  509. */
  510. }
  511. public IAsyncResult BeginAccept(AsyncCallback callback, object state)
  512. {
  513. if (disposed && closed)
  514. throw new ObjectDisposedException (GetType ().ToString ());
  515. if (!isbound || !islistening)
  516. throw new InvalidOperationException ();
  517. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
  518. int count;
  519. lock (readQ) {
  520. readQ.Enqueue (req.Worker);
  521. count = readQ.Count;
  522. }
  523. if (count == 1)
  524. socket_pool_queue (Worker.Dispatcher, req);
  525. return req;
  526. }
  527. public IAsyncResult BeginAccept (int receiveSize,
  528. AsyncCallback callback,
  529. object state)
  530. {
  531. if (disposed && closed)
  532. throw new ObjectDisposedException (GetType ().ToString ());
  533. if (receiveSize < 0)
  534. throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
  535. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
  536. req.Buffer = new byte[receiveSize];
  537. req.Offset = 0;
  538. req.Size = receiveSize;
  539. req.SockFlags = SocketFlags.None;
  540. int count;
  541. lock (readQ) {
  542. readQ.Enqueue (req.Worker);
  543. count = readQ.Count;
  544. }
  545. if (count == 1)
  546. socket_pool_queue (Worker.Dispatcher, req);
  547. return req;
  548. }
  549. public IAsyncResult BeginAccept (Socket acceptSocket,
  550. int receiveSize,
  551. AsyncCallback callback,
  552. object state)
  553. {
  554. if (disposed && closed)
  555. throw new ObjectDisposedException (GetType ().ToString ());
  556. if (receiveSize < 0)
  557. throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
  558. if (acceptSocket != null) {
  559. if (acceptSocket.disposed && acceptSocket.closed)
  560. throw new ObjectDisposedException (acceptSocket.GetType ().ToString ());
  561. if (acceptSocket.IsBound)
  562. throw new InvalidOperationException ();
  563. /* For some reason the MS runtime
  564. * barfs if the new socket is not TCP,
  565. * even though it's just about to blow
  566. * away all those parameters
  567. */
  568. if (acceptSocket.ProtocolType != ProtocolType.Tcp)
  569. throw new SocketException ((int)SocketError.InvalidArgument);
  570. }
  571. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
  572. req.Buffer = new byte[receiveSize];
  573. req.Offset = 0;
  574. req.Size = receiveSize;
  575. req.SockFlags = SocketFlags.None;
  576. req.AcceptSocket = acceptSocket;
  577. int count;
  578. lock (readQ) {
  579. readQ.Enqueue (req.Worker);
  580. count = readQ.Count;
  581. }
  582. if (count == 1)
  583. socket_pool_queue (Worker.Dispatcher, req);
  584. return(req);
  585. }
  586. public IAsyncResult BeginConnect (IPAddress address, int port,
  587. AsyncCallback callback,
  588. object state)
  589. {
  590. if (disposed && closed)
  591. throw new ObjectDisposedException (GetType ().ToString ());
  592. if (address == null)
  593. throw new ArgumentNullException ("address");
  594. if (address.ToString ().Length == 0)
  595. throw new ArgumentException ("The length of the IP address is zero");
  596. if (port <= 0 || port > 65535)
  597. throw new ArgumentOutOfRangeException ("port", "Must be > 0 and < 65536");
  598. if (islistening)
  599. throw new InvalidOperationException ();
  600. IPEndPoint iep = new IPEndPoint (address, port);
  601. return(BeginConnect (iep, callback, state));
  602. }
  603. public IAsyncResult BeginConnect (string host, int port,
  604. AsyncCallback callback,
  605. object state)
  606. {
  607. if (disposed && closed)
  608. throw new ObjectDisposedException (GetType ().ToString ());
  609. if (host == null)
  610. throw new ArgumentNullException ("host");
  611. if (address_family != AddressFamily.InterNetwork &&
  612. address_family != AddressFamily.InterNetworkV6)
  613. throw new NotSupportedException ("This method is valid only for sockets in the InterNetwork and InterNetworkV6 families");
  614. if (port <= 0 || port > 65535)
  615. throw new ArgumentOutOfRangeException ("port", "Must be > 0 and < 65536");
  616. if (islistening)
  617. throw new InvalidOperationException ();
  618. return BeginConnect (Dns.GetHostAddresses (host), port, callback, state);
  619. }
  620. public IAsyncResult BeginDisconnect (bool reuseSocket,
  621. AsyncCallback callback,
  622. object state)
  623. {
  624. if (disposed && closed)
  625. throw new ObjectDisposedException (GetType ().ToString ());
  626. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Disconnect);
  627. req.ReuseSocket = reuseSocket;
  628. socket_pool_queue (Worker.Dispatcher, req);
  629. return(req);
  630. }
  631. void CheckRange (byte[] buffer, int offset, int size)
  632. {
  633. if (offset < 0)
  634. throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
  635. if (offset > buffer.Length)
  636. throw new ArgumentOutOfRangeException ("offset", "offset must be <= buffer.Length");
  637. if (size < 0)
  638. throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
  639. if (size > buffer.Length - offset)
  640. throw new ArgumentOutOfRangeException ("size", "size must be <= buffer.Length - offset");
  641. }
  642. public IAsyncResult BeginReceive(byte[] buffer, int offset,
  643. int size,
  644. SocketFlags socket_flags,
  645. AsyncCallback callback,
  646. object state) {
  647. if (disposed && closed)
  648. throw new ObjectDisposedException (GetType ().ToString ());
  649. if (buffer == null)
  650. throw new ArgumentNullException ("buffer");
  651. CheckRange (buffer, offset, size);
  652. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
  653. req.Buffer = buffer;
  654. req.Offset = offset;
  655. req.Size = size;
  656. req.SockFlags = socket_flags;
  657. int count;
  658. lock (readQ) {
  659. readQ.Enqueue (req.Worker);
  660. count = readQ.Count;
  661. }
  662. if (count == 1)
  663. socket_pool_queue (Worker.Dispatcher, req);
  664. return req;
  665. }
  666. public IAsyncResult BeginReceive (byte[] buffer, int offset,
  667. int size, SocketFlags flags,
  668. out SocketError error,
  669. AsyncCallback callback,
  670. object state)
  671. {
  672. /* As far as I can tell from the docs and from
  673. * experimentation, a pointer to the
  674. * SocketError parameter is not supposed to be
  675. * saved for the async parts. And as we don't
  676. * set any socket errors in the setup code, we
  677. * just have to set it to Success.
  678. */
  679. error = SocketError.Success;
  680. return (BeginReceive (buffer, offset, size, flags, callback, state));
  681. }
  682. [CLSCompliant (false)]
  683. public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
  684. SocketFlags socketFlags,
  685. AsyncCallback callback,
  686. object state)
  687. {
  688. if (disposed && closed)
  689. throw new ObjectDisposedException (GetType ().ToString ());
  690. if (buffers == null)
  691. throw new ArgumentNullException ("buffers");
  692. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveGeneric);
  693. req.Buffers = buffers;
  694. req.SockFlags = socketFlags;
  695. int count;
  696. lock(readQ) {
  697. readQ.Enqueue (req.Worker);
  698. count = readQ.Count;
  699. }
  700. if (count == 1)
  701. socket_pool_queue (Worker.Dispatcher, req);
  702. return req;
  703. }
  704. [CLSCompliant (false)]
  705. public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
  706. SocketFlags socketFlags,
  707. out SocketError errorCode,
  708. AsyncCallback callback,
  709. object state)
  710. {
  711. /* I assume the same SocketError semantics as
  712. * above
  713. */
  714. errorCode = SocketError.Success;
  715. return (BeginReceive (buffers, socketFlags, callback, state));
  716. }
  717. public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
  718. int size,
  719. SocketFlags socket_flags,
  720. ref EndPoint remote_end,
  721. AsyncCallback callback,
  722. object state) {
  723. if (disposed && closed)
  724. throw new ObjectDisposedException (GetType ().ToString ());
  725. if (buffer == null)
  726. throw new ArgumentNullException ("buffer");
  727. if (remote_end == null)
  728. throw new ArgumentNullException ("remote_end");
  729. CheckRange (buffer, offset, size);
  730. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
  731. req.Buffer = buffer;
  732. req.Offset = offset;
  733. req.Size = size;
  734. req.SockFlags = socket_flags;
  735. req.EndPoint = remote_end;
  736. int count;
  737. lock (readQ) {
  738. readQ.Enqueue (req.Worker);
  739. count = readQ.Count;
  740. }
  741. if (count == 1)
  742. socket_pool_queue (Worker.Dispatcher, req);
  743. return req;
  744. }
  745. [MonoTODO]
  746. public IAsyncResult BeginReceiveMessageFrom (
  747. byte[] buffer, int offset, int size,
  748. SocketFlags socketFlags, ref EndPoint remoteEP,
  749. AsyncCallback callback, object state)
  750. {
  751. if (disposed && closed)
  752. throw new ObjectDisposedException (GetType ().ToString ());
  753. if (buffer == null)
  754. throw new ArgumentNullException ("buffer");
  755. if (remoteEP == null)
  756. throw new ArgumentNullException ("remoteEP");
  757. CheckRange (buffer, offset, size);
  758. throw new NotImplementedException ();
  759. }
  760. public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
  761. AsyncCallback callback, object state)
  762. {
  763. if (disposed && closed)
  764. throw new ObjectDisposedException (GetType ().ToString ());
  765. if (buffer == null)
  766. throw new ArgumentNullException ("buffer");
  767. CheckRange (buffer, offset, size);
  768. if (!connected)
  769. throw new SocketException ((int)SocketError.NotConnected);
  770. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
  771. req.Buffer = buffer;
  772. req.Offset = offset;
  773. req.Size = size;
  774. req.SockFlags = socket_flags;
  775. int count;
  776. lock (writeQ) {
  777. writeQ.Enqueue (req.Worker);
  778. count = writeQ.Count;
  779. }
  780. if (count == 1)
  781. socket_pool_queue (Worker.Dispatcher, req);
  782. return req;
  783. }
  784. public IAsyncResult BeginSend (byte[] buffer, int offset,
  785. int size,
  786. SocketFlags socketFlags,
  787. out SocketError errorCode,
  788. AsyncCallback callback,
  789. object state)
  790. {
  791. if (!connected) {
  792. errorCode = SocketError.NotConnected;
  793. throw new SocketException ((int)errorCode);
  794. }
  795. errorCode = SocketError.Success;
  796. return (BeginSend (buffer, offset, size, socketFlags, callback,
  797. state));
  798. }
  799. public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
  800. SocketFlags socketFlags,
  801. AsyncCallback callback,
  802. object state)
  803. {
  804. if (disposed && closed)
  805. throw new ObjectDisposedException (GetType ().ToString ());
  806. if (buffers == null)
  807. throw new ArgumentNullException ("buffers");
  808. if (!connected)
  809. throw new SocketException ((int)SocketError.NotConnected);
  810. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendGeneric);
  811. req.Buffers = buffers;
  812. req.SockFlags = socketFlags;
  813. int count;
  814. lock (writeQ) {
  815. writeQ.Enqueue (req.Worker);
  816. count = writeQ.Count;
  817. }
  818. if (count == 1)
  819. socket_pool_queue (Worker.Dispatcher, req);
  820. return req;
  821. }
  822. [CLSCompliant (false)]
  823. public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
  824. SocketFlags socketFlags,
  825. out SocketError errorCode,
  826. AsyncCallback callback,
  827. object state)
  828. {
  829. if (!connected) {
  830. errorCode = SocketError.NotConnected;
  831. throw new SocketException ((int)errorCode);
  832. }
  833. errorCode = SocketError.Success;
  834. return (BeginSend (buffers, socketFlags, callback, state));
  835. }
  836. delegate void SendFileHandler (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags);
  837. sealed class SendFileAsyncResult : IAsyncResult {
  838. IAsyncResult ares;
  839. SendFileHandler d;
  840. public SendFileAsyncResult (SendFileHandler d, IAsyncResult ares)
  841. {
  842. this.d = d;
  843. this.ares = ares;
  844. }
  845. public object AsyncState {
  846. get { return ares.AsyncState; }
  847. }
  848. public WaitHandle AsyncWaitHandle {
  849. get { return ares.AsyncWaitHandle; }
  850. }
  851. public bool CompletedSynchronously {
  852. get { return ares.CompletedSynchronously; }
  853. }
  854. public bool IsCompleted {
  855. get { return ares.IsCompleted; }
  856. }
  857. public SendFileHandler Delegate {
  858. get { return d; }
  859. }
  860. public IAsyncResult Original {
  861. get { return ares; }
  862. }
  863. }
  864. public IAsyncResult BeginSendFile (string fileName,
  865. AsyncCallback callback,
  866. object state)
  867. {
  868. if (disposed && closed)
  869. throw new ObjectDisposedException (GetType ().ToString ());
  870. if (!connected)
  871. throw new NotSupportedException ();
  872. if (!File.Exists (fileName))
  873. throw new FileNotFoundException ();
  874. return BeginSendFile (fileName, null, null, 0, callback, state);
  875. }
  876. public IAsyncResult BeginSendFile (string fileName,
  877. byte[] preBuffer,
  878. byte[] postBuffer,
  879. TransmitFileOptions flags,
  880. AsyncCallback callback,
  881. object state)
  882. {
  883. if (disposed && closed)
  884. throw new ObjectDisposedException (GetType ().ToString ());
  885. if (!connected)
  886. throw new NotSupportedException ();
  887. if (!File.Exists (fileName))
  888. throw new FileNotFoundException ();
  889. SendFileHandler d = new SendFileHandler (SendFile);
  890. return new SendFileAsyncResult (d, d.BeginInvoke (fileName, preBuffer, postBuffer, flags, ar => {
  891. SendFileAsyncResult sfar = new SendFileAsyncResult (d, ar);
  892. callback (sfar);
  893. }, state));
  894. }
  895. public IAsyncResult BeginSendTo(byte[] buffer, int offset,
  896. int size,
  897. SocketFlags socket_flags,
  898. EndPoint remote_end,
  899. AsyncCallback callback,
  900. object state) {
  901. if (disposed && closed)
  902. throw new ObjectDisposedException (GetType ().ToString ());
  903. if (buffer == null)
  904. throw new ArgumentNullException ("buffer");
  905. CheckRange (buffer, offset, size);
  906. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
  907. req.Buffer = buffer;
  908. req.Offset = offset;
  909. req.Size = size;
  910. req.SockFlags = socket_flags;
  911. req.EndPoint = remote_end;
  912. int count;
  913. lock (writeQ) {
  914. writeQ.Enqueue (req.Worker);
  915. count = writeQ.Count;
  916. }
  917. if (count == 1)
  918. socket_pool_queue (Worker.Dispatcher, req);
  919. return req;
  920. }
  921. // Creates a new system socket, returning the handle
  922. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  923. private extern static void Bind_internal(IntPtr sock,
  924. SocketAddress sa,
  925. out int error);
  926. public void Bind(EndPoint local_end) {
  927. if (disposed && closed)
  928. throw new ObjectDisposedException (GetType ().ToString ());
  929. if (local_end == null)
  930. throw new ArgumentNullException("local_end");
  931. int error;
  932. Bind_internal(socket, local_end.Serialize(), out error);
  933. if (error != 0)
  934. throw new SocketException (error);
  935. if (error == 0)
  936. isbound = true;
  937. seed_endpoint = local_end;
  938. }
  939. public void Connect (IPAddress address, int port)
  940. {
  941. Connect (new IPEndPoint (address, port));
  942. }
  943. public void Connect (IPAddress[] addresses, int port)
  944. {
  945. if (disposed && closed)
  946. throw new ObjectDisposedException (GetType ().ToString ());
  947. if (addresses == null)
  948. throw new ArgumentNullException ("addresses");
  949. if (this.AddressFamily != AddressFamily.InterNetwork &&
  950. this.AddressFamily != AddressFamily.InterNetworkV6)
  951. throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
  952. if (islistening)
  953. throw new InvalidOperationException ();
  954. /* FIXME: do non-blocking sockets Poll here? */
  955. int error = 0;
  956. foreach (IPAddress address in addresses) {
  957. IPEndPoint iep = new IPEndPoint (address, port);
  958. SocketAddress serial = iep.Serialize ();
  959. Connect_internal (socket, serial, out error);
  960. if (error == 0) {
  961. connected = true;
  962. isbound = true;
  963. seed_endpoint = iep;
  964. return;
  965. } else if (error != (int)SocketError.InProgress &&
  966. error != (int)SocketError.WouldBlock) {
  967. continue;
  968. }
  969. if (!blocking) {
  970. Poll (-1, SelectMode.SelectWrite);
  971. error = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
  972. if (error == 0) {
  973. connected = true;
  974. isbound = true;
  975. seed_endpoint = iep;
  976. return;
  977. }
  978. }
  979. }
  980. if (error != 0)
  981. throw new SocketException (error);
  982. }
  983. public void Connect (string host, int port)
  984. {
  985. IPAddress [] addresses = Dns.GetHostAddresses (host);
  986. Connect (addresses, port);
  987. }
  988. public bool DisconnectAsync (SocketAsyncEventArgs e)
  989. {
  990. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  991. if (disposed && closed)
  992. throw new ObjectDisposedException (GetType ().ToString ());
  993. e.curSocket = this;
  994. e.Worker.Init (this, e, SocketOperation.Disconnect);
  995. socket_pool_queue (Worker.Dispatcher, e.Worker.result);
  996. return true;
  997. }
  998. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  999. extern static void Disconnect_internal(IntPtr sock, bool reuse, out int error);
  1000. /* According to the docs, the MS runtime will throw
  1001. * PlatformNotSupportedException if the platform is
  1002. * newer than w2k. We should be able to cope...
  1003. */
  1004. public void Disconnect (bool reuseSocket)
  1005. {
  1006. if (disposed && closed)
  1007. throw new ObjectDisposedException (GetType ().ToString ());
  1008. int error = 0;
  1009. Disconnect_internal (socket, reuseSocket, out error);
  1010. if (error != 0) {
  1011. if (error == 50) {
  1012. /* ERROR_NOT_SUPPORTED */
  1013. throw new PlatformNotSupportedException ();
  1014. } else {
  1015. throw new SocketException (error);
  1016. }
  1017. }
  1018. connected = false;
  1019. if (reuseSocket) {
  1020. /* Do managed housekeeping here... */
  1021. }
  1022. }
  1023. #if !MOBILE
  1024. [MonoLimitation ("We do not support passing sockets across processes, we merely allow this API to pass the socket across AppDomains")]
  1025. public SocketInformation DuplicateAndClose (int targetProcessId)
  1026. {
  1027. var si = new SocketInformation ();
  1028. si.Options =
  1029. (islistening ? SocketInformationOptions.Listening : 0) |
  1030. (connected ? SocketInformationOptions.Connected : 0) |
  1031. (blocking ? 0 : SocketInformationOptions.NonBlocking) |
  1032. (useoverlappedIO ? SocketInformationOptions.UseOnlyOverlappedIO : 0);
  1033. si.ProtocolInformation = Mono.DataConverter.Pack ("iiiil", (int)address_family, (int)socket_type, (int)protocol_type, isbound ? 1 : 0, (long)socket);
  1034. socket = (IntPtr) (-1);
  1035. return si;
  1036. }
  1037. #endif
  1038. public Socket EndAccept (IAsyncResult result)
  1039. {
  1040. int bytes;
  1041. byte[] buffer;
  1042. return(EndAccept (out buffer, out bytes, result));
  1043. }
  1044. public Socket EndAccept (out byte[] buffer, IAsyncResult asyncResult)
  1045. {
  1046. int bytes;
  1047. return(EndAccept (out buffer, out bytes, asyncResult));
  1048. }
  1049. public Socket EndAccept (out byte[] buffer, out int bytesTransferred, IAsyncResult asyncResult)
  1050. {
  1051. if (disposed && closed)
  1052. throw new ObjectDisposedException (GetType ().ToString ());
  1053. if (asyncResult == null)
  1054. throw new ArgumentNullException ("asyncResult");
  1055. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  1056. if (req == null)
  1057. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  1058. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1059. throw InvalidAsyncOp ("EndAccept");
  1060. if (!asyncResult.IsCompleted)
  1061. asyncResult.AsyncWaitHandle.WaitOne ();
  1062. req.CheckIfThrowDelayedException ();
  1063. buffer = req.Buffer;
  1064. bytesTransferred = req.Total;
  1065. return(req.Socket);
  1066. }
  1067. public void EndConnect (IAsyncResult result)
  1068. {
  1069. if (disposed && closed)
  1070. throw new ObjectDisposedException (GetType ().ToString ());
  1071. if (result == null)
  1072. throw new ArgumentNullException ("result");
  1073. SocketAsyncResult req = result as SocketAsyncResult;
  1074. if (req == null)
  1075. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1076. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1077. throw InvalidAsyncOp ("EndConnect");
  1078. if (!result.IsCompleted)
  1079. result.AsyncWaitHandle.WaitOne();
  1080. req.CheckIfThrowDelayedException();
  1081. }
  1082. public void EndDisconnect (IAsyncResult asyncResult)
  1083. {
  1084. if (disposed && closed)
  1085. throw new ObjectDisposedException (GetType ().ToString ());
  1086. if (asyncResult == null)
  1087. throw new ArgumentNullException ("asyncResult");
  1088. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  1089. if (req == null)
  1090. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  1091. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1092. throw InvalidAsyncOp ("EndDisconnect");
  1093. if (!asyncResult.IsCompleted)
  1094. asyncResult.AsyncWaitHandle.WaitOne ();
  1095. req.CheckIfThrowDelayedException ();
  1096. }
  1097. [MonoTODO]
  1098. public int EndReceiveMessageFrom (IAsyncResult asyncResult,
  1099. ref SocketFlags socketFlags,
  1100. ref EndPoint endPoint,
  1101. out IPPacketInformation ipPacketInformation)
  1102. {
  1103. if (disposed && closed)
  1104. throw new ObjectDisposedException (GetType ().ToString ());
  1105. if (asyncResult == null)
  1106. throw new ArgumentNullException ("asyncResult");
  1107. if (endPoint == null)
  1108. throw new ArgumentNullException ("endPoint");
  1109. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  1110. if (req == null)
  1111. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  1112. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1113. throw InvalidAsyncOp ("EndReceiveMessageFrom");
  1114. throw new NotImplementedException ();
  1115. }
  1116. public void EndSendFile (IAsyncResult asyncResult)
  1117. {
  1118. if (disposed && closed)
  1119. throw new ObjectDisposedException (GetType ().ToString ());
  1120. if (asyncResult == null)
  1121. throw new ArgumentNullException ("asyncResult");
  1122. SendFileAsyncResult ares = asyncResult as SendFileAsyncResult;
  1123. if (ares == null)
  1124. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  1125. ares.Delegate.EndInvoke (ares.Original);
  1126. }
  1127. public int EndSendTo (IAsyncResult result)
  1128. {
  1129. if (disposed && closed)
  1130. throw new ObjectDisposedException (GetType ().ToString ());
  1131. if (result == null)
  1132. throw new ArgumentNullException ("result");
  1133. SocketAsyncResult req = result as SocketAsyncResult;
  1134. if (req == null)
  1135. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1136. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1137. throw InvalidAsyncOp ("EndSendTo");
  1138. if (!result.IsCompleted)
  1139. result.AsyncWaitHandle.WaitOne();
  1140. req.CheckIfThrowDelayedException();
  1141. return req.Total;
  1142. }
  1143. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1144. private extern static void GetSocketOption_arr_internal(IntPtr socket,
  1145. SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val,
  1146. out int error);
  1147. public void GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
  1148. {
  1149. if (disposed && closed)
  1150. throw new ObjectDisposedException (GetType ().ToString ());
  1151. if (optionValue == null)
  1152. throw new SocketException ((int) SocketError.Fault,
  1153. "Error trying to dereference an invalid pointer");
  1154. int error;
  1155. GetSocketOption_arr_internal (socket, optionLevel, optionName, ref optionValue,
  1156. out error);
  1157. if (error != 0)
  1158. throw new SocketException (error);
  1159. }
  1160. public byte [] GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, int length)
  1161. {
  1162. if (disposed && closed)
  1163. throw new ObjectDisposedException (GetType ().ToString ());
  1164. byte[] byte_val=new byte[length];
  1165. int error;
  1166. GetSocketOption_arr_internal (socket, optionLevel, optionName, ref byte_val,
  1167. out error);
  1168. if (error != 0)
  1169. throw new SocketException (error);
  1170. return(byte_val);
  1171. }
  1172. // See Socket.IOControl, WSAIoctl documentation in MSDN. The
  1173. // common options between UNIX and Winsock are FIONREAD,
  1174. // FIONBIO and SIOCATMARK. Anything else will depend on the
  1175. // system except SIO_KEEPALIVE_VALS which is properly handled
  1176. // on both windows and linux.
  1177. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1178. extern static int WSAIoctl (IntPtr sock, int ioctl_code, byte [] input,
  1179. byte [] output, out int error);
  1180. public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
  1181. {
  1182. if (disposed)
  1183. throw new ObjectDisposedException (GetType ().ToString ());
  1184. int error;
  1185. int result = WSAIoctl (socket, ioctl_code, in_value, out_value,
  1186. out error);
  1187. if (error != 0)
  1188. throw new SocketException (error);
  1189. if (result == -1)
  1190. throw new InvalidOperationException ("Must use Blocking property instead.");
  1191. return result;
  1192. }
  1193. public int IOControl (IOControlCode ioControlCode, byte[] optionInValue, byte[] optionOutValue)
  1194. {
  1195. return IOControl ((int) ioControlCode, optionInValue, optionOutValue);
  1196. }
  1197. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1198. private extern static void Listen_internal(IntPtr sock, int backlog, out int error);
  1199. public void Listen (int backlog)
  1200. {
  1201. if (disposed && closed)
  1202. throw new ObjectDisposedException (GetType ().ToString ());
  1203. if (!isbound)
  1204. throw new SocketException ((int)SocketError.InvalidArgument);
  1205. int error;
  1206. Listen_internal(socket, backlog, out error);
  1207. if (error != 0)
  1208. throw new SocketException (error);
  1209. islistening = true;
  1210. }
  1211. public bool Poll (int time_us, SelectMode mode)
  1212. {
  1213. if (disposed && closed)
  1214. throw new ObjectDisposedException (GetType ().ToString ());
  1215. if (mode != SelectMode.SelectRead &&
  1216. mode != SelectMode.SelectWrite &&
  1217. mode != SelectMode.SelectError)
  1218. throw new NotSupportedException ("'mode' parameter is not valid.");
  1219. int error;
  1220. bool result = Poll_internal (socket, mode, time_us, out error);
  1221. if (error != 0)
  1222. throw new SocketException (error);
  1223. if (mode == SelectMode.SelectWrite && result && !connected) {
  1224. /* Update the connected state; for
  1225. * non-blocking Connect()s this is
  1226. * when we can find out that the
  1227. * connect succeeded.
  1228. */
  1229. if ((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
  1230. connected = true;
  1231. }
  1232. }
  1233. return result;
  1234. }
  1235. public int Receive (byte [] buffer)
  1236. {
  1237. if (disposed && closed)
  1238. throw new ObjectDisposedException (GetType ().ToString ());
  1239. if (buffer == null)
  1240. throw new ArgumentNullException ("buffer");
  1241. SocketError error;
  1242. int ret = Receive_nochecks (buffer, 0, buffer.Length, SocketFlags.None, out error);
  1243. if (error != SocketError.Success)
  1244. throw new SocketException ((int) error);
  1245. return ret;
  1246. }
  1247. public int Receive (byte [] buffer, SocketFlags flags)
  1248. {
  1249. if (disposed && closed)
  1250. throw new ObjectDisposedException (GetType ().ToString ());
  1251. if (buffer == null)
  1252. throw new ArgumentNullException ("buffer");
  1253. SocketError error;
  1254. int ret = Receive_nochecks (buffer, 0, buffer.Length, flags, out error);
  1255. if (error != SocketError.Success) {
  1256. if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
  1257. throw new SocketException ((int) error, "Operation timed out.");
  1258. throw new SocketException ((int) error);
  1259. }
  1260. return ret;
  1261. }
  1262. public int Receive (byte [] buffer, int size, SocketFlags flags)
  1263. {
  1264. if (disposed && closed)
  1265. throw new ObjectDisposedException (GetType ().ToString ());
  1266. if (buffer == null)
  1267. throw new ArgumentNullException ("buffer");
  1268. CheckRange (buffer, 0, size);
  1269. SocketError error;
  1270. int ret = Receive_nochecks (buffer, 0, size, flags, out error);
  1271. if (error != SocketError.Success) {
  1272. if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
  1273. throw new SocketException ((int) error, "Operation timed out.");
  1274. throw new SocketException ((int) error);
  1275. }
  1276. return ret;
  1277. }
  1278. public int Receive (byte [] buffer, int offset, int size, SocketFlags flags)
  1279. {
  1280. if (disposed && closed)
  1281. throw new ObjectDisposedException (GetType ().ToString ());
  1282. if (buffer == null)
  1283. throw new ArgumentNullException ("buffer");
  1284. CheckRange (buffer, offset, size);
  1285. SocketError error;
  1286. int ret = Receive_nochecks (buffer, offset, size, flags, out error);
  1287. if (error != SocketError.Success) {
  1288. if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
  1289. throw new SocketException ((int) error, "Operation timed out.");
  1290. throw new SocketException ((int) error);
  1291. }
  1292. return ret;
  1293. }
  1294. public int Receive (byte [] buffer, int offset, int size, SocketFlags flags, out SocketError error)
  1295. {
  1296. if (disposed && closed)
  1297. throw new ObjectDisposedException (GetType ().ToString ());
  1298. if (buffer == null)
  1299. throw new ArgumentNullException ("buffer");
  1300. CheckRange (buffer, offset, size);
  1301. return Receive_nochecks (buffer, offset, size, flags, out error);
  1302. }
  1303. public bool ReceiveFromAsync (SocketAsyncEventArgs e)
  1304. {
  1305. if (disposed && closed)
  1306. throw new ObjectDisposedException (GetType ().ToString ());
  1307. // We do not support recv into multiple buffers yet
  1308. if (e.BufferList != null)
  1309. throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
  1310. if (e.RemoteEndPoint == null)
  1311. throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
  1312. e.curSocket = this;
  1313. e.Worker.Init (this, e, SocketOperation.ReceiveFrom);
  1314. SocketAsyncResult res = e.Worker.result;
  1315. res.Buffer = e.Buffer;
  1316. res.Offset = e.Offset;
  1317. res.Size = e.Count;
  1318. res.EndPoint = e.RemoteEndPoint;
  1319. res.SockFlags = e.SocketFlags;
  1320. int count;
  1321. lock (readQ) {
  1322. readQ.Enqueue (e.Worker);
  1323. count = readQ.Count;
  1324. }
  1325. if (count == 1)
  1326. socket_pool_queue (Worker.Dispatcher, res);
  1327. return true;
  1328. }
  1329. public int ReceiveFrom (byte [] buffer, ref EndPoint remoteEP)
  1330. {
  1331. if (disposed && closed)
  1332. throw new ObjectDisposedException (GetType ().ToString ());
  1333. if (buffer == null)
  1334. throw new ArgumentNullException ("buffer");
  1335. if (remoteEP == null)
  1336. throw new ArgumentNullException ("remoteEP");
  1337. return ReceiveFrom_nochecks (buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP);
  1338. }
  1339. public int ReceiveFrom (byte [] buffer, SocketFlags flags, ref EndPoint remoteEP)
  1340. {
  1341. if (disposed && closed)
  1342. throw new ObjectDisposedException (GetType ().ToString ());
  1343. if (buffer == null)
  1344. throw new ArgumentNullException ("buffer");
  1345. if (remoteEP == null)
  1346. throw new ArgumentNullException ("remoteEP");
  1347. return ReceiveFrom_nochecks (buffer, 0, buffer.Length, flags, ref remoteEP);
  1348. }
  1349. public int ReceiveFrom (byte [] buffer, int size, SocketFlags flags,
  1350. ref EndPoint remoteEP)
  1351. {
  1352. if (disposed && closed)
  1353. throw new ObjectDisposedException (GetType ().ToString ());
  1354. if (buffer == null)
  1355. throw new ArgumentNullException ("buffer");
  1356. if (remoteEP == null)
  1357. throw new ArgumentNullException ("remoteEP");
  1358. if (size < 0 || size > buffer.Length)
  1359. throw new ArgumentOutOfRangeException ("size");
  1360. return ReceiveFrom_nochecks (buffer, 0, size, flags, ref remoteEP);
  1361. }
  1362. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1363. private extern static int RecvFrom_internal(IntPtr sock,
  1364. byte[] buffer,
  1365. int offset,
  1366. int count,
  1367. SocketFlags flags,
  1368. ref SocketAddress sockaddr,
  1369. out int error);
  1370. public int ReceiveFrom (byte [] buffer, int offset, int size, SocketFlags flags,
  1371. ref EndPoint remoteEP)
  1372. {
  1373. if (disposed && closed)
  1374. throw new ObjectDisposedException (GetType ().ToString ());
  1375. if (buffer == null)
  1376. throw new ArgumentNullException ("buffer");
  1377. if (remoteEP == null)
  1378. throw new ArgumentNullException ("remoteEP");
  1379. CheckRange (buffer, offset, size);
  1380. return ReceiveFrom_nochecks (buffer, offset, size, flags, ref remoteEP);
  1381. }
  1382. internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
  1383. ref EndPoint remote_end)
  1384. {
  1385. int error;
  1386. return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
  1387. }
  1388. internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags,
  1389. ref EndPoint remote_end, bool throwOnError, out int error)
  1390. {
  1391. SocketAddress sockaddr = remote_end.Serialize();
  1392. int cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
  1393. SocketError err = (SocketError) error;
  1394. if (err != 0) {
  1395. if (err != SocketError.WouldBlock && err != SocketError.InProgress)
  1396. connected = false;
  1397. else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
  1398. if (throwO

Large files files are truncated, but you can click here to view the full file