PageRenderTime 70ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://bitbucket.org/steenlund/mono-2.6.7-for-amiga
C# | 3145 lines | 2361 code | 579 blank | 205 comment | 773 complexity | 4c24ed54c4c8bbbf6480a4f139b7baaa MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0, LGPL-2.1

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-2006 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.Runtime.CompilerServices;
  38. using System.Runtime.InteropServices;
  39. using System.Threading;
  40. using System.Reflection;
  41. using System.IO;
  42. using System.Net.Configuration;
  43. using System.Text;
  44. #if NET_2_0
  45. using System.Collections.Generic;
  46. using System.Net.NetworkInformation;
  47. using System.Timers;
  48. #endif
  49. namespace System.Net.Sockets
  50. {
  51. public partial class Socket : IDisposable
  52. {
  53. enum SocketOperation {
  54. Accept,
  55. Connect,
  56. Receive,
  57. ReceiveFrom,
  58. Send,
  59. SendTo,
  60. UsedInManaged1,
  61. UsedInManaged2,
  62. UsedInProcess,
  63. UsedInConsole2,
  64. Disconnect,
  65. AcceptReceive,
  66. ReceiveGeneric,
  67. SendGeneric
  68. }
  69. [StructLayout (LayoutKind.Sequential)]
  70. struct WSABUF
  71. {
  72. public int len;
  73. public IntPtr buf;
  74. };
  75. [StructLayout (LayoutKind.Sequential)]
  76. private sealed class SocketAsyncResult: IAsyncResult
  77. {
  78. /* Same structure in the runtime */
  79. /*
  80. Keep this in sync with MonoSocketAsyncResult in
  81. metadata/socket-io.h and ProcessAsyncReader
  82. in System.Diagnostics/Process.cs.
  83. */
  84. public Socket Sock;
  85. public IntPtr handle;
  86. object state;
  87. AsyncCallback callback;
  88. WaitHandle waithandle;
  89. Exception delayedException;
  90. public EndPoint EndPoint; // Connect,ReceiveFrom,SendTo
  91. public byte [] Buffer; // Receive,ReceiveFrom,Send,SendTo
  92. public int Offset; // Receive,ReceiveFrom,Send,SendTo
  93. public int Size; // Receive,ReceiveFrom,Send,SendTo
  94. public SocketFlags SockFlags; // Receive,ReceiveFrom,Send,SendTo
  95. public Socket AcceptSocket; // AcceptReceive
  96. public IPAddress[] Addresses; // Connect
  97. public int Port; // Connect
  98. #if NET_2_0
  99. public IList<ArraySegment<byte>> Buffers; // Receive, Send
  100. #else
  101. public object Buffers; // Reserve this slot in older profiles
  102. #endif
  103. public bool ReuseSocket; // Disconnect
  104. // Return values
  105. Socket acc_socket;
  106. int total;
  107. bool completed_sync;
  108. bool completed;
  109. public bool blocking;
  110. internal int error;
  111. SocketOperation operation;
  112. public object ares;
  113. public int EndCalled;
  114. public SocketAsyncResult (Socket sock, object state, AsyncCallback callback, SocketOperation operation)
  115. {
  116. this.Sock = sock;
  117. this.blocking = sock.blocking;
  118. this.handle = sock.socket;
  119. this.state = state;
  120. this.callback = callback;
  121. this.operation = operation;
  122. SockFlags = SocketFlags.None;
  123. }
  124. public void CheckIfThrowDelayedException ()
  125. {
  126. if (delayedException != null) {
  127. Sock.connected = false;
  128. throw delayedException;
  129. }
  130. if (error != 0) {
  131. Sock.connected = false;
  132. throw new SocketException (error);
  133. }
  134. }
  135. void CompleteAllOnDispose (Queue queue)
  136. {
  137. object [] pending = queue.ToArray ();
  138. queue.Clear ();
  139. WaitCallback cb;
  140. for (int i = 0; i < pending.Length; i++) {
  141. SocketAsyncResult ares = (SocketAsyncResult) pending [i];
  142. cb = new WaitCallback (ares.CompleteDisposed);
  143. ThreadPool.QueueUserWorkItem (cb, null);
  144. }
  145. if (pending.Length == 0)
  146. Buffer = null;
  147. }
  148. void CompleteDisposed (object unused)
  149. {
  150. Complete ();
  151. }
  152. public void Complete ()
  153. {
  154. if (operation != SocketOperation.Receive && Sock.disposed)
  155. delayedException = new ObjectDisposedException (Sock.GetType ().ToString ());
  156. IsCompleted = true;
  157. Queue queue = null;
  158. if (operation == SocketOperation.Receive || operation == SocketOperation.ReceiveFrom) {
  159. queue = Sock.readQ;
  160. } else if (operation == SocketOperation.Send || operation == SocketOperation.SendTo) {
  161. queue = Sock.writeQ;
  162. }
  163. if (queue != null) {
  164. SocketAsyncCall sac = null;
  165. SocketAsyncResult req = null;
  166. lock (queue) {
  167. queue.Dequeue (); // remove ourselves
  168. if (queue.Count > 0) {
  169. req = (SocketAsyncResult) queue.Peek ();
  170. if (!Sock.disposed) {
  171. Worker worker = new Worker (req);
  172. sac = GetDelegate (worker, req.operation);
  173. } else {
  174. CompleteAllOnDispose (queue);
  175. }
  176. }
  177. }
  178. if (sac != null)
  179. sac.BeginInvoke (null, req);
  180. }
  181. if (callback != null)
  182. callback (this);
  183. Buffer = null;
  184. }
  185. SocketAsyncCall GetDelegate (Worker worker, SocketOperation op)
  186. {
  187. switch (op) {
  188. case SocketOperation.Receive:
  189. return new SocketAsyncCall (worker.Receive);
  190. case SocketOperation.ReceiveFrom:
  191. return new SocketAsyncCall (worker.ReceiveFrom);
  192. case SocketOperation.Send:
  193. return new SocketAsyncCall (worker.Send);
  194. case SocketOperation.SendTo:
  195. return new SocketAsyncCall (worker.SendTo);
  196. default:
  197. return null; // never happens
  198. }
  199. }
  200. public void Complete (bool synch)
  201. {
  202. completed_sync = synch;
  203. Complete ();
  204. }
  205. public void Complete (int total)
  206. {
  207. this.total = total;
  208. Complete ();
  209. }
  210. public void Complete (Exception e, bool synch)
  211. {
  212. completed_sync = synch;
  213. delayedException = e;
  214. Complete ();
  215. }
  216. public void Complete (Exception e)
  217. {
  218. delayedException = e;
  219. Complete ();
  220. }
  221. public void Complete (Socket s)
  222. {
  223. acc_socket = s;
  224. Complete ();
  225. }
  226. public void Complete (Socket s, int total)
  227. {
  228. acc_socket = s;
  229. this.total = total;
  230. Complete ();
  231. }
  232. public object AsyncState {
  233. get {
  234. return state;
  235. }
  236. }
  237. public WaitHandle AsyncWaitHandle {
  238. get {
  239. lock (this) {
  240. if (waithandle == null)
  241. waithandle = new ManualResetEvent (completed);
  242. }
  243. return waithandle;
  244. }
  245. set {
  246. waithandle=value;
  247. }
  248. }
  249. public bool CompletedSynchronously {
  250. get {
  251. return(completed_sync);
  252. }
  253. }
  254. public bool IsCompleted {
  255. get {
  256. return(completed);
  257. }
  258. set {
  259. completed=value;
  260. lock (this) {
  261. if (waithandle != null && value) {
  262. ((ManualResetEvent) waithandle).Set ();
  263. }
  264. }
  265. }
  266. }
  267. public Socket Socket {
  268. get {
  269. return acc_socket;
  270. }
  271. }
  272. public int Total {
  273. get { return total; }
  274. set { total = value; }
  275. }
  276. public SocketError ErrorCode
  277. {
  278. get {
  279. #if NET_2_0
  280. SocketException ex = delayedException as SocketException;
  281. if (ex != null)
  282. return(ex.SocketErrorCode);
  283. if (error != 0)
  284. return((SocketError)error);
  285. #endif
  286. return(SocketError.Success);
  287. }
  288. }
  289. }
  290. private sealed class Worker
  291. {
  292. SocketAsyncResult result;
  293. public Worker (SocketAsyncResult ares)
  294. {
  295. this.result = ares;
  296. }
  297. public void Accept ()
  298. {
  299. Socket acc_socket = null;
  300. try {
  301. acc_socket = result.Sock.Accept ();
  302. } catch (Exception e) {
  303. result.Complete (e);
  304. return;
  305. }
  306. result.Complete (acc_socket);
  307. }
  308. /* only used in 2.0 profile and newer, but
  309. * leave in older profiles to keep interface
  310. * to runtime consistent
  311. */
  312. public void AcceptReceive ()
  313. {
  314. Socket acc_socket = null;
  315. try {
  316. if (result.AcceptSocket == null) {
  317. acc_socket = result.Sock.Accept ();
  318. } else {
  319. acc_socket = result.AcceptSocket;
  320. result.Sock.Accept (acc_socket);
  321. }
  322. } catch (Exception e) {
  323. result.Complete (e);
  324. return;
  325. }
  326. /* It seems the MS runtime
  327. * special-cases 0-length requested
  328. * receive data. See bug 464201.
  329. */
  330. int total = 0;
  331. if (result.Size > 0) {
  332. try {
  333. SocketError error;
  334. total = acc_socket.Receive_nochecks (result.Buffer,
  335. result.Offset,
  336. result.Size,
  337. result.SockFlags,
  338. out error);
  339. } catch (Exception e) {
  340. result.Complete (e);
  341. return;
  342. }
  343. }
  344. result.Complete (acc_socket, total);
  345. }
  346. public void Connect ()
  347. {
  348. /* If result.EndPoint is non-null,
  349. * this is the standard one-address
  350. * connect attempt. Otherwise
  351. * Addresses must be non-null and
  352. * contain a list of addresses to try
  353. * to connect to; the first one to
  354. * succeed causes the rest of the list
  355. * to be ignored.
  356. */
  357. if (result.EndPoint != null) {
  358. try {
  359. if (!result.Sock.Blocking) {
  360. int success;
  361. result.Sock.Poll (-1, SelectMode.SelectWrite, out success);
  362. if (success == 0) {
  363. result.Sock.connected = true;
  364. } else {
  365. result.Complete (new SocketException (success));
  366. return;
  367. }
  368. } else {
  369. result.Sock.seed_endpoint = result.EndPoint;
  370. result.Sock.Connect (result.EndPoint);
  371. result.Sock.connected = true;
  372. }
  373. } catch (Exception e) {
  374. result.Complete (e);
  375. return;
  376. }
  377. result.Complete ();
  378. } else if (result.Addresses != null) {
  379. int error = (int) SocketError.InProgress; // why?
  380. foreach(IPAddress address in result.Addresses) {
  381. IPEndPoint iep = new IPEndPoint (address, result.Port);
  382. SocketAddress serial = iep.Serialize ();
  383. Socket.Connect_internal (result.Sock.socket, serial, out error);
  384. if (error == 0) {
  385. result.Sock.connected = true;
  386. result.Sock.seed_endpoint = iep;
  387. result.Complete ();
  388. return;
  389. } else if (error != (int)SocketError.InProgress &&
  390. error != (int)SocketError.WouldBlock) {
  391. continue;
  392. }
  393. if (!result.Sock.Blocking) {
  394. int success;
  395. result.Sock.Poll (-1, SelectMode.SelectWrite, out success);
  396. if (success == 0) {
  397. result.Sock.connected = true;
  398. result.Sock.seed_endpoint = iep;
  399. result.Complete ();
  400. return;
  401. }
  402. }
  403. }
  404. result.Complete (new SocketException (error));
  405. } else {
  406. result.Complete (new SocketException ((int)SocketError.AddressNotAvailable));
  407. }
  408. }
  409. /* Also only used in 2.0 profile and newer */
  410. public void Disconnect ()
  411. {
  412. #if NET_2_0
  413. try {
  414. result.Sock.Disconnect (result.ReuseSocket);
  415. } catch (Exception e) {
  416. result.Complete (e);
  417. return;
  418. }
  419. result.Complete ();
  420. #else
  421. result.Complete (new SocketException ((int)SocketError.Fault));
  422. #endif
  423. }
  424. public void Receive ()
  425. {
  426. // Actual recv() done in the runtime
  427. result.Complete ();
  428. }
  429. public void ReceiveFrom ()
  430. {
  431. int total = 0;
  432. try {
  433. total = result.Sock.ReceiveFrom_nochecks (result.Buffer,
  434. result.Offset,
  435. result.Size,
  436. result.SockFlags,
  437. ref result.EndPoint);
  438. } catch (Exception e) {
  439. result.Complete (e);
  440. return;
  441. }
  442. result.Complete (total);
  443. }
  444. public void ReceiveGeneric ()
  445. {
  446. #if NET_2_0
  447. int total = 0;
  448. try {
  449. SocketError error;
  450. total = result.Sock.Receive (result.Buffers, result.SockFlags, out error);
  451. } catch (Exception e) {
  452. result.Complete (e);
  453. return;
  454. }
  455. result.Complete (total);
  456. #else
  457. result.Complete (new SocketException ((int)SocketError.Fault));
  458. #endif
  459. }
  460. int send_so_far;
  461. void UpdateSendValues (int last_sent)
  462. {
  463. if (result.error == 0) {
  464. send_so_far += last_sent;
  465. result.Offset += last_sent;
  466. result.Size -= last_sent;
  467. }
  468. }
  469. public void Send ()
  470. {
  471. // Actual send() done in the runtime
  472. if (result.error == 0) {
  473. UpdateSendValues (result.Total);
  474. if (result.Sock.disposed) {
  475. result.Complete ();
  476. return;
  477. }
  478. if (result.Size > 0) {
  479. SocketAsyncCall sac = new SocketAsyncCall (this.Send);
  480. sac.BeginInvoke (null, result);
  481. return; // Have to finish writing everything. See bug #74475.
  482. }
  483. result.Total = send_so_far;
  484. }
  485. result.Complete ();
  486. }
  487. public void SendTo ()
  488. {
  489. int total = 0;
  490. try {
  491. total = result.Sock.SendTo_nochecks (result.Buffer,
  492. result.Offset,
  493. result.Size,
  494. result.SockFlags,
  495. result.EndPoint);
  496. UpdateSendValues (total);
  497. if (result.Size > 0) {
  498. SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
  499. sac.BeginInvoke (null, result);
  500. return; // Have to finish writing everything. See bug #74475.
  501. }
  502. result.Total = send_so_far;
  503. } catch (Exception e) {
  504. result.Complete (e);
  505. return;
  506. }
  507. result.Complete ();
  508. }
  509. public void SendGeneric ()
  510. {
  511. #if NET_2_0
  512. int total = 0;
  513. try {
  514. SocketError error;
  515. total = result.Sock.Send (result.Buffers, result.SockFlags, out error);
  516. } catch (Exception e) {
  517. result.Complete (e);
  518. return;
  519. }
  520. result.Complete (total);
  521. #else
  522. result.Complete (new SocketException ((int)SocketError.Fault));
  523. #endif
  524. }
  525. }
  526. private Queue readQ = new Queue (2);
  527. private Queue writeQ = new Queue (2);
  528. delegate void SocketAsyncCall ();
  529. #if NET_2_0
  530. private bool islistening;
  531. private bool useoverlappedIO;
  532. #endif
  533. static void AddSockets (ArrayList sockets, IList list, string name)
  534. {
  535. if (list != null) {
  536. foreach (Socket sock in list) {
  537. if (sock == null) // MS throws a NullRef
  538. throw new ArgumentNullException ("name", "Contains a null element");
  539. sockets.Add (sock);
  540. }
  541. }
  542. sockets.Add (null);
  543. }
  544. #if !TARGET_JVM
  545. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  546. private extern static void Select_internal (ref Socket [] sockets,
  547. int microSeconds,
  548. out int error);
  549. #endif
  550. public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
  551. {
  552. ArrayList list = new ArrayList ();
  553. AddSockets (list, checkRead, "checkRead");
  554. AddSockets (list, checkWrite, "checkWrite");
  555. AddSockets (list, checkError, "checkError");
  556. if (list.Count == 3) {
  557. throw new ArgumentNullException ("checkRead, checkWrite, checkError",
  558. "All the lists are null or empty.");
  559. }
  560. int error;
  561. /*
  562. * The 'sockets' array contains: READ socket 0-n, null,
  563. * WRITE socket 0-n, null,
  564. * ERROR socket 0-n, null
  565. */
  566. Socket [] sockets = (Socket []) list.ToArray (typeof (Socket));
  567. Select_internal (ref sockets, microSeconds, out error);
  568. if (error != 0)
  569. throw new SocketException (error);
  570. if (sockets == null) {
  571. if (checkRead != null)
  572. checkRead.Clear ();
  573. if (checkWrite != null)
  574. checkWrite.Clear ();
  575. if (checkError != null)
  576. checkError.Clear ();
  577. return;
  578. }
  579. int mode = 0;
  580. int count = sockets.Length;
  581. IList currentList = checkRead;
  582. int currentIdx = 0;
  583. for (int i = 0; i < count; i++) {
  584. Socket cur_sock;
  585. Socket sock = sockets [i];
  586. if (sock == null) { // separator
  587. if (currentList != null) {
  588. // Remove non-signaled sockets after the current one
  589. int to_remove = currentList.Count - currentIdx;
  590. for (int k = 0; k < to_remove; k++)
  591. currentList.RemoveAt (currentIdx);
  592. }
  593. currentList = (mode == 0) ? checkWrite : checkError;
  594. currentIdx = 0;
  595. mode++;
  596. continue;
  597. }
  598. if (mode == 1 && currentList == checkWrite && !sock.connected) {
  599. if ((int) sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0)
  600. sock.connected = true;
  601. }
  602. // Remove non-signaled sockets before the current one
  603. int max = currentList.Count;
  604. while ((cur_sock = (Socket) currentList [currentIdx]) != sock) {
  605. currentList.RemoveAt (currentIdx);
  606. }
  607. currentIdx++;
  608. }
  609. }
  610. // private constructor used by Accept, which already
  611. // has a socket handle to use
  612. private Socket(AddressFamily family, SocketType type,
  613. ProtocolType proto, IntPtr sock)
  614. {
  615. address_family=family;
  616. socket_type=type;
  617. protocol_type=proto;
  618. socket=sock;
  619. connected=true;
  620. }
  621. private void SocketDefaults ()
  622. {
  623. #if NET_2_0
  624. try {
  625. if (address_family == AddressFamily.InterNetwork /* Need to test IPv6 further ||
  626. address_family == AddressFamily.InterNetworkV6 */) {
  627. /* This is the default, but it
  628. * probably has nasty side
  629. * effects on Linux, as the
  630. * socket option is kludged by
  631. * turning on or off PMTU
  632. * discovery...
  633. */
  634. this.DontFragment = false;
  635. }
  636. //
  637. // Microsoft sets these to 8192, but we are going to keep them
  638. // both to the OS defaults as these have a big performance impact.
  639. // on WebClient performance.
  640. //
  641. //this.ReceiveBufferSize = 8192;
  642. //this.SendBufferSize = 8192;
  643. } catch (SocketException) {
  644. }
  645. #endif
  646. }
  647. #if NET_2_0
  648. [MonoTODO]
  649. public Socket (SocketInformation socketInformation)
  650. {
  651. throw new NotImplementedException ("SocketInformation not figured out yet");
  652. // ifdef to avoid the warnings.
  653. #if false
  654. //address_family = socketInformation.address_family;
  655. //socket_type = socketInformation.socket_type;
  656. //protocol_type = socketInformation.protocol_type;
  657. address_family = AddressFamily.InterNetwork;
  658. socket_type = SocketType.Stream;
  659. protocol_type = ProtocolType.IP;
  660. int error;
  661. socket = Socket_internal (address_family, socket_type, protocol_type, out error);
  662. if (error != 0)
  663. throw new SocketException (error);
  664. SocketDefaults ();
  665. #endif
  666. }
  667. #endif
  668. #if !TARGET_JVM
  669. // Returns the amount of data waiting to be read on socket
  670. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  671. private extern static int Available_internal(IntPtr socket, out int error);
  672. #endif
  673. public int Available {
  674. get {
  675. if (disposed && closed)
  676. throw new ObjectDisposedException (GetType ().ToString ());
  677. int ret, error;
  678. ret = Available_internal(socket, out error);
  679. if (error != 0)
  680. throw new SocketException (error);
  681. return(ret);
  682. }
  683. }
  684. #if NET_2_0
  685. public bool DontFragment {
  686. get {
  687. if (disposed && closed) {
  688. throw new ObjectDisposedException (GetType ().ToString ());
  689. }
  690. bool dontfragment;
  691. if (address_family == AddressFamily.InterNetwork) {
  692. dontfragment = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment)) != 0;
  693. } else if (address_family == AddressFamily.InterNetworkV6) {
  694. dontfragment = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment)) != 0;
  695. } else {
  696. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  697. }
  698. return(dontfragment);
  699. }
  700. set {
  701. if (disposed && closed) {
  702. throw new ObjectDisposedException (GetType ().ToString ());
  703. }
  704. if (address_family == AddressFamily.InterNetwork) {
  705. SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment, value?1:0);
  706. } else if (address_family == AddressFamily.InterNetworkV6) {
  707. SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment, value?1:0);
  708. } else {
  709. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  710. }
  711. }
  712. }
  713. public bool EnableBroadcast {
  714. get {
  715. if (disposed && closed) {
  716. throw new ObjectDisposedException (GetType ().ToString ());
  717. }
  718. if (protocol_type != ProtocolType.Udp) {
  719. throw new SocketException ((int)SocketError.ProtocolOption);
  720. }
  721. return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast)) != 0);
  722. }
  723. set {
  724. if (disposed && closed) {
  725. throw new ObjectDisposedException (GetType ().ToString ());
  726. }
  727. if (protocol_type != ProtocolType.Udp) {
  728. throw new SocketException ((int)SocketError.ProtocolOption);
  729. }
  730. SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast, value?1:0);
  731. }
  732. }
  733. public bool ExclusiveAddressUse {
  734. get {
  735. if (disposed && closed) {
  736. throw new ObjectDisposedException (GetType ().ToString ());
  737. }
  738. return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse)) != 0);
  739. }
  740. set {
  741. if (disposed && closed) {
  742. throw new ObjectDisposedException (GetType ().ToString ());
  743. }
  744. if (isbound) {
  745. throw new InvalidOperationException ("Bind has already been called for this socket");
  746. }
  747. SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, value?1:0);
  748. }
  749. }
  750. public bool IsBound {
  751. get {
  752. return(isbound);
  753. }
  754. }
  755. public LingerOption LingerState {
  756. get {
  757. if (disposed && closed) {
  758. throw new ObjectDisposedException (GetType ().ToString ());
  759. }
  760. return((LingerOption)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Linger));
  761. }
  762. set {
  763. if (disposed && closed) {
  764. throw new ObjectDisposedException (GetType ().ToString ());
  765. }
  766. SetSocketOption (SocketOptionLevel.Socket,
  767. SocketOptionName.Linger,
  768. value);
  769. }
  770. }
  771. public bool MulticastLoopback {
  772. get {
  773. if (disposed && closed) {
  774. throw new ObjectDisposedException (GetType ().ToString ());
  775. }
  776. /* Even though this option can be set
  777. * for TCP sockets on Linux, throw
  778. * this exception anyway to be
  779. * compatible (the MSDN docs say
  780. * "Setting this property on a
  781. * Transmission Control Protocol (TCP)
  782. * socket will have no effect." but
  783. * the MS runtime throws the
  784. * exception...)
  785. */
  786. if (protocol_type == ProtocolType.Tcp) {
  787. throw new SocketException ((int)SocketError.ProtocolOption);
  788. }
  789. bool multicastloopback;
  790. if (address_family == AddressFamily.InterNetwork) {
  791. multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback)) != 0;
  792. } else if (address_family == AddressFamily.InterNetworkV6) {
  793. multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback)) != 0;
  794. } else {
  795. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  796. }
  797. return(multicastloopback);
  798. }
  799. set {
  800. if (disposed && closed) {
  801. throw new ObjectDisposedException (GetType ().ToString ());
  802. }
  803. /* Even though this option can be set
  804. * for TCP sockets on Linux, throw
  805. * this exception anyway to be
  806. * compatible (the MSDN docs say
  807. * "Setting this property on a
  808. * Transmission Control Protocol (TCP)
  809. * socket will have no effect." but
  810. * the MS runtime throws the
  811. * exception...)
  812. */
  813. if (protocol_type == ProtocolType.Tcp) {
  814. throw new SocketException ((int)SocketError.ProtocolOption);
  815. }
  816. if (address_family == AddressFamily.InterNetwork) {
  817. SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, value?1:0);
  818. } else if (address_family == AddressFamily.InterNetworkV6) {
  819. SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback, value?1:0);
  820. } else {
  821. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  822. }
  823. }
  824. }
  825. [MonoTODO ("This doesn't do anything on Mono yet")]
  826. public bool UseOnlyOverlappedIO {
  827. get {
  828. return(useoverlappedIO);
  829. }
  830. set {
  831. useoverlappedIO = value;
  832. }
  833. }
  834. #endif
  835. public IntPtr Handle {
  836. get {
  837. return(socket);
  838. }
  839. }
  840. #if !TARGET_JVM
  841. // Returns the local endpoint details in addr and port
  842. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  843. private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, out int error);
  844. #endif
  845. // Wish: support non-IP endpoints.
  846. public EndPoint LocalEndPoint {
  847. get {
  848. if (disposed && closed)
  849. throw new ObjectDisposedException (GetType ().ToString ());
  850. /*
  851. * If the seed EndPoint is null, Connect, Bind,
  852. * etc has not yet been called. MS returns null
  853. * in this case.
  854. */
  855. if (seed_endpoint == null)
  856. return null;
  857. SocketAddress sa;
  858. int error;
  859. sa=LocalEndPoint_internal(socket, out error);
  860. if (error != 0)
  861. throw new SocketException (error);
  862. return seed_endpoint.Create (sa);
  863. }
  864. }
  865. public SocketType SocketType {
  866. get {
  867. return(socket_type);
  868. }
  869. }
  870. #if NET_2_0
  871. public int SendTimeout {
  872. get {
  873. if (disposed && closed)
  874. throw new ObjectDisposedException (GetType ().ToString ());
  875. return (int)GetSocketOption(
  876. SocketOptionLevel.Socket,
  877. SocketOptionName.SendTimeout);
  878. }
  879. set {
  880. if (disposed && closed)
  881. throw new ObjectDisposedException (GetType ().ToString ());
  882. if (value < -1)
  883. throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
  884. /* According to the MSDN docs we
  885. * should adjust values between 1 and
  886. * 499 to 500, but the MS runtime
  887. * doesn't do this.
  888. */
  889. if (value == -1)
  890. value = 0;
  891. SetSocketOption(
  892. SocketOptionLevel.Socket,
  893. SocketOptionName.SendTimeout, value);
  894. }
  895. }
  896. public int ReceiveTimeout {
  897. get {
  898. if (disposed && closed)
  899. throw new ObjectDisposedException (GetType ().ToString ());
  900. return (int)GetSocketOption(
  901. SocketOptionLevel.Socket,
  902. SocketOptionName.ReceiveTimeout);
  903. }
  904. set {
  905. if (disposed && closed)
  906. throw new ObjectDisposedException (GetType ().ToString ());
  907. if (value < -1)
  908. throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
  909. if (value == -1) {
  910. value = 0;
  911. }
  912. SetSocketOption(
  913. SocketOptionLevel.Socket,
  914. SocketOptionName.ReceiveTimeout, value);
  915. }
  916. }
  917. public bool AcceptAsync (SocketAsyncEventArgs e)
  918. {
  919. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  920. if (disposed && closed)
  921. throw new ObjectDisposedException (GetType ().ToString ());
  922. if (!IsBound)
  923. throw new InvalidOperationException ("You must call the Bind method before performing this operation.");
  924. if (!islistening)
  925. throw new InvalidOperationException ("You must call the Listen method before performing this operation.");
  926. if (e.BufferList != null)
  927. throw new ArgumentException ("Multiple buffers cannot be used with this method.");
  928. if (e.Count < 0)
  929. throw new ArgumentOutOfRangeException ("e.Count");
  930. Socket acceptSocket = e.AcceptSocket;
  931. if (acceptSocket != null) {
  932. if (acceptSocket.IsBound || acceptSocket.Connected)
  933. throw new InvalidOperationException ("AcceptSocket: The socket must not be bound or connected.");
  934. } else
  935. e.AcceptSocket = new Socket (AddressFamily, SocketType, ProtocolType);
  936. try {
  937. e.DoOperation (SocketAsyncOperation.Accept, this);
  938. } catch {
  939. ((IDisposable)e).Dispose ();
  940. throw;
  941. }
  942. // We always return true for now
  943. return true;
  944. }
  945. #endif
  946. // Creates a new system socket, returning the handle
  947. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  948. private extern static IntPtr Accept_internal(IntPtr sock, out int error, bool blocking);
  949. public Socket Accept() {
  950. if (disposed && closed)
  951. throw new ObjectDisposedException (GetType ().ToString ());
  952. int error = 0;
  953. IntPtr sock = (IntPtr) (-1);
  954. blocking_thread = Thread.CurrentThread;
  955. try {
  956. sock = Accept_internal(socket, out error, blocking);
  957. } catch (ThreadAbortException) {
  958. if (disposed) {
  959. Thread.ResetAbort ();
  960. error = (int) SocketError.Interrupted;
  961. }
  962. } finally {
  963. blocking_thread = null;
  964. }
  965. if (error != 0)
  966. throw new SocketException (error);
  967. Socket accepted = new Socket(this.AddressFamily, this.SocketType,
  968. this.ProtocolType, sock);
  969. accepted.seed_endpoint = this.seed_endpoint;
  970. accepted.Blocking = this.Blocking;
  971. return(accepted);
  972. }
  973. internal void Accept (Socket acceptSocket)
  974. {
  975. if (disposed && closed)
  976. throw new ObjectDisposedException (GetType ().ToString ());
  977. int error = 0;
  978. IntPtr sock = (IntPtr)(-1);
  979. blocking_thread = Thread.CurrentThread;
  980. try {
  981. sock = Accept_internal (socket, out error, blocking);
  982. } catch (ThreadAbortException) {
  983. if (disposed) {
  984. Thread.ResetAbort ();
  985. error = (int)SocketError.Interrupted;
  986. }
  987. } finally {
  988. blocking_thread = null;
  989. }
  990. if (error != 0)
  991. throw new SocketException (error);
  992. acceptSocket.address_family = this.AddressFamily;
  993. acceptSocket.socket_type = this.SocketType;
  994. acceptSocket.protocol_type = this.ProtocolType;
  995. acceptSocket.socket = sock;
  996. acceptSocket.connected = true;
  997. acceptSocket.seed_endpoint = this.seed_endpoint;
  998. acceptSocket.Blocking = this.Blocking;
  999. /* FIXME: figure out what if anything else
  1000. * needs to be reset
  1001. */
  1002. }
  1003. public IAsyncResult BeginAccept(AsyncCallback callback,
  1004. object state)
  1005. {
  1006. if (disposed && closed)
  1007. throw new ObjectDisposedException (GetType ().ToString ());
  1008. #if NET_2_0
  1009. /* FIXME: check the 1.1 docs for this too */
  1010. if (!isbound || !islistening)
  1011. throw new InvalidOperationException ();
  1012. #endif
  1013. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
  1014. Worker worker = new Worker (req);
  1015. SocketAsyncCall sac = new SocketAsyncCall (worker.Accept);
  1016. sac.BeginInvoke (null, req);
  1017. return(req);
  1018. }
  1019. #if NET_2_0
  1020. public IAsyncResult BeginAccept (int receiveSize,
  1021. AsyncCallback callback,
  1022. object state)
  1023. {
  1024. if (disposed && closed)
  1025. throw new ObjectDisposedException (GetType ().ToString ());
  1026. if (receiveSize < 0)
  1027. throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
  1028. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
  1029. Worker worker = new Worker (req);
  1030. SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
  1031. req.Buffer = new byte[receiveSize];
  1032. req.Offset = 0;
  1033. req.Size = receiveSize;
  1034. req.SockFlags = SocketFlags.None;
  1035. sac.BeginInvoke (null, req);
  1036. return(req);
  1037. }
  1038. public IAsyncResult BeginAccept (Socket acceptSocket,
  1039. int receiveSize,
  1040. AsyncCallback callback,
  1041. object state)
  1042. {
  1043. if (disposed && closed)
  1044. throw new ObjectDisposedException (GetType ().ToString ());
  1045. if (receiveSize < 0)
  1046. throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
  1047. if (acceptSocket != null) {
  1048. if (acceptSocket.disposed && acceptSocket.closed)
  1049. throw new ObjectDisposedException (acceptSocket.GetType ().ToString ());
  1050. if (acceptSocket.IsBound)
  1051. throw new InvalidOperationException ();
  1052. /* For some reason the MS runtime
  1053. * barfs if the new socket is not TCP,
  1054. * even though it's just about to blow
  1055. * away all those parameters
  1056. */
  1057. if (acceptSocket.ProtocolType != ProtocolType.Tcp)
  1058. throw new SocketException ((int)SocketError.InvalidArgument);
  1059. }
  1060. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
  1061. Worker worker = new Worker (req);
  1062. SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
  1063. req.Buffer = new byte[receiveSize];
  1064. req.Offset = 0;
  1065. req.Size = receiveSize;
  1066. req.SockFlags = SocketFlags.None;
  1067. req.AcceptSocket = acceptSocket;
  1068. sac.BeginInvoke (null, req);
  1069. return(req);
  1070. }
  1071. #endif
  1072. public IAsyncResult BeginConnect(EndPoint end_point,
  1073. AsyncCallback callback,
  1074. object state) {
  1075. if (disposed && closed)
  1076. throw new ObjectDisposedException (GetType ().ToString ());
  1077. if (end_point == null)
  1078. throw new ArgumentNullException ("end_point");
  1079. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
  1080. req.EndPoint = end_point;
  1081. // Bug #75154: Connect() should not succeed for .Any addresses.
  1082. if (end_point is IPEndPoint) {
  1083. IPEndPoint ep = (IPEndPoint) end_point;
  1084. if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any)) {
  1085. req.Complete (new SocketException ((int) SocketError.AddressNotAvailable), true);
  1086. return req;
  1087. }
  1088. }
  1089. int error = 0;
  1090. if (!blocking) {
  1091. SocketAddress serial = end_point.Serialize ();
  1092. Connect_internal (socket, serial, out error);
  1093. if (error == 0) {
  1094. // succeeded synch
  1095. connected = true;
  1096. req.Complete (true);
  1097. } else if (error != (int) SocketError.InProgress && error != (int) SocketError.WouldBlock) {
  1098. // error synch
  1099. connected = false;
  1100. req.Complete (new SocketException (error), true);
  1101. }
  1102. }
  1103. if (blocking || error == (int) SocketError.InProgress || error == (int) SocketError.WouldBlock) {
  1104. // continue asynch
  1105. connected = false;
  1106. Worker worker = new Worker (req);
  1107. SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
  1108. sac.BeginInvoke (null, req);
  1109. }
  1110. return(req);
  1111. }
  1112. #if NET_2_0
  1113. public IAsyncResult BeginConnect (IPAddress address, int port,
  1114. AsyncCallback callback,
  1115. object state)
  1116. {
  1117. if (disposed && closed)
  1118. throw new ObjectDisposedException (GetType ().ToString ());
  1119. if (address == null)
  1120. throw new ArgumentNullException ("address");
  1121. if (address.ToString ().Length == 0)
  1122. throw new ArgumentException ("The length of the IP address is zero");
  1123. if (islistening)
  1124. throw new InvalidOperationException ();
  1125. IPEndPoint iep = new IPEndPoint (address, port);
  1126. return(BeginConnect (iep, callback, state));
  1127. }
  1128. public IAsyncResult BeginConnect (IPAddress[] addresses,
  1129. int port,
  1130. AsyncCallback callback,
  1131. object state)
  1132. {
  1133. if (disposed && closed)
  1134. throw new ObjectDisposedException (GetType ().ToString ());
  1135. if (addresses == null)
  1136. throw new ArgumentNullException ("addresses");
  1137. if (this.AddressFamily != AddressFamily.InterNetwork &&
  1138. this.AddressFamily != AddressFamily.InterNetworkV6)
  1139. throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
  1140. if (islistening)
  1141. throw new InvalidOperationException ();
  1142. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
  1143. req.Addresses = addresses;
  1144. req.Port = port;
  1145. connected = false;
  1146. Worker worker = new Worker (req);
  1147. SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
  1148. sac.BeginInvoke (null, req);
  1149. return(req);
  1150. }
  1151. public IAsyncResult BeginConnect (string host, int port,
  1152. AsyncCallback callback,
  1153. object state)
  1154. {
  1155. if (disposed && closed)
  1156. throw new ObjectDisposedException (GetType ().ToString ());
  1157. if (host == null)
  1158. throw new ArgumentNullException ("host");
  1159. if (address_family != AddressFamily.InterNetwork &&
  1160. address_family != AddressFamily.InterNetworkV6)
  1161. throw new NotSupportedException ("This method is valid only for sockets in the InterNetwork and InterNetworkV6 families");
  1162. if (islistening)
  1163. throw new InvalidOperationException ();
  1164. IPAddress [] addresses = Dns.GetHostAddresses (host);
  1165. return (BeginConnect (addresses, port, callback, state));
  1166. }
  1167. public IAsyncResult BeginDisconnect (bool reuseSocket,
  1168. AsyncCallback callback,
  1169. object state)
  1170. {
  1171. if (disposed && closed)
  1172. throw new ObjectDisposedException (GetType ().ToString ());
  1173. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Disconnect);
  1174. req.ReuseSocket = reuseSocket;
  1175. Worker worker = new Worker (req);
  1176. SocketAsyncCall sac = new SocketAsyncCall (worker.Disconnect);
  1177. sac.BeginInvoke (null, req);
  1178. return(req);
  1179. }
  1180. #endif
  1181. public IAsyncResult BeginReceive(byte[] buffer, int offset,
  1182. int size,
  1183. SocketFlags socket_flags,
  1184. AsyncCallback callback,
  1185. object state) {
  1186. if (disposed && closed)
  1187. throw new ObjectDisposedException (GetType ().ToString ());
  1188. if (buffer == null)
  1189. throw new ArgumentNullException ("buffer");
  1190. if (offset < 0 || offset > buffer.Length)
  1191. throw new ArgumentOutOfRangeException ("offset");
  1192. if (size < 0 || offset + size > buffer.Length)
  1193. throw new ArgumentOutOfRangeException ("size");
  1194. SocketAsyncResult req;
  1195. lock (readQ) {
  1196. req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
  1197. req.Buffer = buffer;
  1198. req.Offset = offset;
  1199. req.Size = size;
  1200. req.SockFlags = socket_flags;
  1201. readQ.Enqueue (req);
  1202. if (readQ.Count == 1) {
  1203. Worker worker = new Worker (req);
  1204. SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
  1205. sac.BeginInvoke (null, req);
  1206. }
  1207. }
  1208. return req;
  1209. }
  1210. #if NET_2_0
  1211. public IAsyncResult BeginReceive (byte[] buffer, int offset,
  1212. int size, SocketFlags flags,
  1213. out SocketError error,
  1214. AsyncCallback callback,
  1215. object state)
  1216. {
  1217. /* As far as I can tell from the docs and from
  1218. * experimentation, a pointer to the
  1219. * SocketError parameter is not supposed to be
  1220. * saved for the async parts. And as we don't
  1221. * set any socket errors in the setup code, we
  1222. * just have to set it to Success.
  1223. */
  1224. error = SocketError.Success;
  1225. return (BeginReceive (buffer, offset, size, flags, callback, state));
  1226. }
  1227. [CLSCompliant (false)]
  1228. public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
  1229. SocketFlags socketFlags,
  1230. AsyncCallback callback,
  1231. object state)
  1232. {
  1233. if (disposed && closed)
  1234. throw new ObjectDisposedException (GetType ().ToString ());
  1235. if (buffers == null)
  1236. throw new ArgumentNullException ("buffers");
  1237. SocketAsyncResult req;
  1238. lock(readQ) {
  1239. req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveGeneric);
  1240. req.Buffers = buffers;
  1241. req.SockFlags = socketFlags;
  1242. readQ.Enqueue (req);
  1243. if (readQ.Count == 1) {
  1244. Worker worker = new Worker (req);
  1245. SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveGeneric);
  1246. sac.BeginInvoke (null, req);
  1247. }
  1248. }
  1249. return(req);
  1250. }
  1251. [CLSCompliant (false)]
  1252. public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
  1253. SocketFlags socketFlags,
  1254. out SocketError errorCode,
  1255. AsyncCallback callback,
  1256. object state)
  1257. {
  1258. /* I assume the same SocketError semantics as
  1259. * above
  1260. */
  1261. errorCode = SocketError.Success;
  1262. return (BeginReceive (buffers, socketFlags, callback, state));
  1263. }
  1264. #endif
  1265. public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
  1266. int size,
  1267. SocketFlags socket_flags,
  1268. ref EndPoint remote_end,
  1269. AsyncCallback callback,
  1270. object state) {
  1271. if (disposed && closed)
  1272. throw new ObjectDisposedException (GetType ().ToString ());
  1273. if (buffer == null)
  1274. throw new ArgumentNullException ("buffer");
  1275. if (offset < 0)
  1276. throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
  1277. if (size < 0)
  1278. throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
  1279. if (offset + size > buffer.Length)
  1280. throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
  1281. SocketAsyncResult req;
  1282. lock (readQ) {
  1283. req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
  1284. req.Buffer = buffer;
  1285. req.Offset = offset;
  1286. req.Size = size;
  1287. req.SockFlags = socket_flags;
  1288. req.EndPoint = remote_end;
  1289. readQ.Enqueue (req);
  1290. if (readQ.Count == 1) {
  1291. Worker worker = new Worker (req);
  1292. SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
  1293. sac.BeginInvoke (null, req);
  1294. }
  1295. }
  1296. return req;
  1297. }
  1298. #if NET_2_0
  1299. [MonoTODO]
  1300. public IAsyncResult BeginReceiveMessageFrom (
  1301. byte[] buffer, int offset, int size,
  1302. SocketFlags socketFlags, ref EndPoint remoteEP,
  1303. AsyncCallback callback, object state)
  1304. {
  1305. if (disposed && closed)
  1306. throw new ObjectDisposedException (GetType ().ToString ());
  1307. if (buffer == null)
  1308. throw new ArgumentNullException ("buffer");
  1309. if (remoteEP == null)
  1310. throw new ArgumentNullException ("remoteEP");
  1311. if (offset < 0 || offset > buffer.Length)
  1312. throw new ArgumentOutOfRangeException ("offset");
  1313. if (size < 0 || offset + size > buffer.Length)
  1314. throw new ArgumentOutOfRangeException ("size");
  1315. throw new NotImplementedException ();
  1316. }
  1317. #endif
  1318. public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
  1319. AsyncCallback callback, object state)
  1320. {
  1321. if (disposed && closed)
  1322. throw new ObjectDisposedException (GetType ().ToString ());
  1323. if (buffer == null)
  1324. throw new ArgumentNullException ("buffer");
  1325. if (offset < 0)
  1326. throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
  1327. if (size < 0)
  1328. throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
  1329. if (offset + size > buffer.Length)
  1330. throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
  1331. #if NET_2_0
  1332. /* TODO: Check this exception in the 1.1 profile */
  1333. if (!connected)
  1334. throw new SocketException ((int)SocketError.NotConnected);
  1335. #endif
  1336. SocketAsyncResult req;
  1337. lock (writeQ) {
  1338. req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
  1339. req.Buffer = buffer;
  1340. req.Offset = offset;
  1341. req.Size = size;
  1342. req.SockFlags = socket_flags;
  1343. writeQ.Enqueue (req);
  1344. if (writeQ.Count == 1) {
  1345. Worker worker = new Worker (req);
  1346. SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
  1347. sac.BeginInvoke (null, req);
  1348. }
  1349. }
  1350. return req;
  1351. }
  1352. #if NET_2_0
  1353. public IAsyncResult BeginSend (byte[] buffer, int offset,
  1354. int size,
  1355. SocketFlags socketFlags,
  1356. out SocketError errorCode,
  1357. AsyncCallback callback,
  1358. object state)
  1359. {
  1360. if (!connected) {
  1361. errorCode = SocketError.NotConnected;
  1362. throw new SocketException ((int)errorCode);
  1363. }
  1364. errorCode = SocketError.Success;
  1365. return (BeginSend (buffer, offset, size, socketFlags, callback,
  1366. state));
  1367. }
  1368. public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
  1369. SocketFlags socketFlags,
  1370. AsyncCallback callback,
  1371. object state)
  1372. {
  1373. if (disposed && closed)
  1374. throw new ObjectDisposedException (GetType ().ToString ());
  1375. if (buffers == null)
  1376. throw new ArgumentNullException ("buffers");
  1377. if (!connected)
  1378. throw new SocketException ((int)SocketError.NotConnected);
  1379. SocketAsyncResult req;
  1380. lock (writeQ) {
  1381. req = new SocketAsyncResult (this, state, callback, SocketOperation.SendGeneric);
  1382. req.Buffers = buffers;
  1383. req.SockFlags = socketFlags;
  1384. writeQ.Enqueue (req);
  1385. if (writeQ.Count == 1) {
  1386. Worker worker = new Worker (req);
  1387. SocketAsyncCall sac = new SocketAsyncCall (worker.SendGeneric);
  1388. sac.BeginInvoke (null, req);
  1389. }
  1390. }
  1391. return(req);
  1392. }
  1393. [CLSCompliant (false)]
  1394. public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
  1395. SocketFlags socketFlags,
  1396. out SocketError errorCode,
  1397. AsyncCallback callback,
  1398. object state)
  1399. {
  1400. if (!connected) {
  1401. errorCode = SocketError.NotConnected;
  1402. throw new SocketException ((int)errorCode);
  1403. }
  1404. errorCode = SocketError.Success;
  1405. return (BeginSend (buffers, socketFlags, callback, state));
  1406. }
  1407. delegate void SendFileHandler (string fileName, byte [] preBuffer, byte [] postBuffer, TransmitFileOptions flags);
  1408. sealed class SendFileAsyncResult : IAsyncResult {
  1409. IAsyncResult ares;
  1410. SendFileHandler d;
  1411. public SendFileAsyncResult (SendFileHandler d, IAsyncResult ares)
  1412. {
  1413. this.d = d;
  1414. this.ares = ares;
  1415. }
  1416. public object AsyncState {
  1417. get { return ares.AsyncState; }
  1418. }
  1419. public WaitHandle AsyncWaitHandle {
  1420. get { return ares.AsyncWaitHandle; }
  1421. }
  1422. public bool CompletedSynchronously {
  1423. get { return ares.CompletedSynchronously; }
  1424. }
  1425. public bool IsCompleted {
  1426. get { return ares.IsCompleted; }
  1427. }
  1428. public SendFileHandler Delegate {
  1429. get { return d; }
  1430. }
  1431. public IAsyncResult Original {
  1432. get { return ares; }
  1433. }
  1434. }
  1435. public IAsyncResult BeginSendFile (string fileName,
  1436. AsyncCallback callback,
  1437. object state)
  1438. {
  1439. if (disposed && closed)
  1440. throw new ObjectDisposedException (GetType ().ToString ());
  1441. if (!connected)
  1442. throw new NotSupportedException ();
  1443. if (!File.Exists (fileName))
  1444. throw new FileNotFoundException ();
  1445. return BeginSendFile (fileName, null, null, 0, callback, state);
  1446. }
  1447. public IAsyncResult BeginSendFile (string fileName,
  1448. byte[] preBuffer,
  1449. byte[] postBuffer,
  1450. TransmitFileOptions flags,
  1451. AsyncCallback callback,
  1452. object state)
  1453. {
  1454. if (disposed && closed)
  1455. throw new ObjectDisposedException (GetType ().ToString ());
  1456. if (!connected)
  1457. throw new NotSupportedException ();
  1458. if (!File.Exists (fileName))
  1459. throw new FileNotFoundException ();
  1460. SendFileHandler d = new SendFileHandler (SendFile);
  1461. return new SendFileAsyncResult (d, d.BeginInvoke (fileName, preBuffer, postBuffer, flags, callback, state));
  1462. }
  1463. #endif
  1464. public IAsyncResult BeginSendTo(byte[] buffer, int offset,
  1465. int size,
  1466. SocketFlags socket_flags,
  1467. EndPoint remote_end,
  1468. AsyncCallback callback,
  1469. object state) {
  1470. if (disposed && closed)
  1471. throw new ObjectDisposedException (GetType ().ToString ());
  1472. if (buffer == null)
  1473. throw new ArgumentNullException ("buffer");
  1474. if (offset < 0)
  1475. throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
  1476. if (size < 0)
  1477. throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
  1478. if (offset + size > buffer.Length)
  1479. throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
  1480. SocketAsyncResult req;
  1481. lock (writeQ) {
  1482. req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
  1483. req.Buffer = buffer;
  1484. req.Offset = offset;
  1485. req.Size = size;
  1486. req.SockFlags = socket_flags;
  1487. req.EndPoint = remote_end;
  1488. writeQ.Enqueue (req);
  1489. if (writeQ.Count == 1) {
  1490. Worker worker = new Worker (req);
  1491. SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
  1492. sac.BeginInvoke (null, req);
  1493. }
  1494. }
  1495. return req;
  1496. }
  1497. // Creates a new system socket, returning the handle
  1498. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1499. private extern static void Bind_internal(IntPtr sock,
  1500. SocketAddress sa,
  1501. out int error);
  1502. public void Bind(EndPoint local_end) {
  1503. if (disposed && closed)
  1504. throw new ObjectDisposedException (GetType ().ToString ());
  1505. if (local_end == null)
  1506. throw new ArgumentNullException("local_end");
  1507. int error;
  1508. Bind_internal(socket, local_end.Serialize(), out error);
  1509. if (error != 0)
  1510. throw new SocketException (error);
  1511. #if NET_2_0
  1512. if (error == 0)
  1513. isbound = true;
  1514. #endif
  1515. seed_endpoint = local_end;
  1516. }
  1517. #if NET_2_0
  1518. public bool ConnectAsync (SocketAsyncEventArgs e)
  1519. {
  1520. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  1521. if (disposed && closed)
  1522. throw new ObjectDisposedException (GetType ().ToString ());
  1523. if (islistening)
  1524. throw new InvalidOperationException ("You may not perform this operation after calling the Listen method.");
  1525. if (e.RemoteEndPoint == null)
  1526. throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
  1527. if (e.BufferList != null)
  1528. throw new ArgumentException ("Multiple buffers cannot be used with this method.");
  1529. e.DoOperation (SocketAsyncOperation.Connect, this);
  1530. // We always return true for now
  1531. return true;
  1532. }
  1533. #endif
  1534. #if NET_2_0
  1535. public void Connect (IPAddress address, int port)
  1536. {
  1537. Connect (new IPEndPoint (address, port));
  1538. }
  1539. public void Connect (IPAddress[] addresses, int port)
  1540. {
  1541. if (disposed && closed)
  1542. throw new ObjectDisposedException (GetType ().ToString ());
  1543. if (addresses == null)
  1544. throw new ArgumentNullException ("addresses");
  1545. if (this.AddressFamily != AddressFamily.InterNetwork &&
  1546. this.AddressFamily != AddressFamily.InterNetworkV6)
  1547. throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
  1548. if (islistening)
  1549. throw new InvalidOperationException ();
  1550. /* FIXME: do non-blocking sockets Poll here? */
  1551. int error = 0;
  1552. foreach (IPAddress address in addresses) {
  1553. IPEndPoint iep = new IPEndPoint (address, port);
  1554. SocketAddress serial = iep.Serialize ();
  1555. Connect_internal (socket, serial, out error);
  1556. if (error == 0) {
  1557. connected = true;
  1558. seed_endpoint = iep;
  1559. return;
  1560. } else if (error != (int)SocketError.InProgress &&
  1561. error != (int)SocketError.WouldBlock) {
  1562. continue;
  1563. }
  1564. if (!blocking) {
  1565. Poll (-1, SelectMod

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