PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://bitbucket.org/danipen/mono
C# | 2586 lines | 2047 code | 440 blank | 99 comment | 352 complexity | 959051b1be5dd347ffb7765196052441 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. //
  8. // Copyright (C) 2001, 2002 Phillip Pearson and Ximian, Inc.
  9. // http://www.myelin.co.nz
  10. // (c) 2004 Novell, Inc. (http://www.novell.com)
  11. //
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining
  14. // a copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to
  18. // permit persons to whom the Software is furnished to do so, subject to
  19. // the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be
  22. // included in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. //
  32. using System.Collections;
  33. using System.Collections.Generic;
  34. using System.Net.Configuration;
  35. using System.Runtime.InteropServices;
  36. using System.Threading;
  37. namespace System.Net.Sockets
  38. {
  39. public class Socket : IDisposable
  40. {
  41. enum SocketOperation
  42. {
  43. Accept,
  44. Connect,
  45. Receive,
  46. ReceiveFrom,
  47. Send,
  48. SendTo
  49. }
  50. [StructLayout (LayoutKind.Sequential)]
  51. private sealed class SocketAsyncResult: IAsyncResult
  52. {
  53. /* Same structure in the runtime */
  54. public Socket Sock;
  55. #if !TARGET_JVM
  56. public IntPtr handle;
  57. #else
  58. public GHSocket handle;
  59. #endif
  60. object state;
  61. AsyncCallback callback;
  62. WaitHandle waithandle;
  63. Exception delayedException;
  64. public EndPoint EndPoint; // Connect,ReceiveFrom,SendTo
  65. public byte [] Buffer; // Receive,ReceiveFrom,Send,SendTo
  66. public int Offset; // Receive,ReceiveFrom,Send,SendTo
  67. public int Size; // Receive,ReceiveFrom,Send,SendTo
  68. public SocketFlags SockFlags; // Receive,ReceiveFrom,Send,SendTo
  69. // Return values
  70. Socket acc_socket;
  71. int total;
  72. bool completed_sync;
  73. bool completed;
  74. public bool blocking;
  75. internal int error;
  76. SocketOperation operation;
  77. public object ares;
  78. public SocketAsyncResult (Socket sock, object state, AsyncCallback callback, SocketOperation operation)
  79. {
  80. this.Sock = sock;
  81. this.blocking = sock.blocking;
  82. this.handle = sock.socket;
  83. this.state = state;
  84. this.callback = callback;
  85. this.operation = operation;
  86. SockFlags = SocketFlags.None;
  87. }
  88. public void CheckIfThrowDelayedException ()
  89. {
  90. if (delayedException != null)
  91. throw delayedException;
  92. if (error != 0)
  93. throw new SocketException (error);
  94. }
  95. void CompleteAllOnDispose (Queue queue)
  96. {
  97. object [] pending = queue.ToArray ();
  98. queue.Clear ();
  99. WaitCallback cb;
  100. for (int i = 0; i < pending.Length; i++)
  101. {
  102. SocketAsyncResult ares = (SocketAsyncResult) pending [i];
  103. cb = new WaitCallback (ares.CompleteDisposed);
  104. ThreadPool.QueueUserWorkItem (cb, null);
  105. }
  106. }
  107. void CompleteDisposed (object unused)
  108. {
  109. Complete ();
  110. }
  111. public void Complete ()
  112. {
  113. if (operation != SocketOperation.Receive && Sock.disposed)
  114. delayedException = new ObjectDisposedException (Sock.GetType ().ToString ());
  115. IsCompleted = true;
  116. Queue queue = null;
  117. if (operation == SocketOperation.Receive || operation == SocketOperation.ReceiveFrom)
  118. {
  119. queue = Sock.readQ;
  120. }
  121. else if (operation == SocketOperation.Send || operation == SocketOperation.SendTo)
  122. {
  123. queue = Sock.writeQ;
  124. }
  125. if (queue != null)
  126. {
  127. SocketAsyncCall sac = null;
  128. SocketAsyncResult req = null;
  129. lock (queue)
  130. {
  131. queue.Dequeue (); // remove ourselves
  132. if (queue.Count > 0)
  133. {
  134. req = (SocketAsyncResult) queue.Peek ();
  135. if (!Sock.disposed)
  136. {
  137. Worker worker = new Worker (req);
  138. sac = GetDelegate (worker, req.operation);
  139. }
  140. else
  141. {
  142. CompleteAllOnDispose (queue);
  143. }
  144. }
  145. }
  146. if (sac != null)
  147. sac.BeginInvoke (null, req);
  148. }
  149. if (callback != null)
  150. callback (this);
  151. }
  152. SocketAsyncCall GetDelegate (Worker worker, SocketOperation op)
  153. {
  154. switch (op)
  155. {
  156. case SocketOperation.Receive:
  157. return new SocketAsyncCall (worker.Receive);
  158. case SocketOperation.ReceiveFrom:
  159. return new SocketAsyncCall (worker.ReceiveFrom);
  160. case SocketOperation.Send:
  161. return new SocketAsyncCall (worker.Send);
  162. case SocketOperation.SendTo:
  163. return new SocketAsyncCall (worker.SendTo);
  164. default:
  165. return null; // never happens
  166. }
  167. }
  168. public void Complete (bool synch)
  169. {
  170. completed_sync = synch;
  171. Complete ();
  172. }
  173. public void Complete (int total)
  174. {
  175. this.total = total;
  176. Complete ();
  177. }
  178. public void Complete (Exception e, bool synch)
  179. {
  180. completed_sync = synch;
  181. delayedException = e;
  182. Complete ();
  183. }
  184. public void Complete (Exception e)
  185. {
  186. delayedException = e;
  187. Complete ();
  188. }
  189. public void Complete (Socket s)
  190. {
  191. acc_socket = s;
  192. Complete ();
  193. }
  194. public object AsyncState
  195. {
  196. get
  197. {
  198. return state;
  199. }
  200. }
  201. public WaitHandle AsyncWaitHandle
  202. {
  203. get
  204. {
  205. lock (this)
  206. {
  207. if (waithandle == null)
  208. waithandle = new ManualResetEvent (completed);
  209. }
  210. return waithandle;
  211. }
  212. set
  213. {
  214. waithandle=value;
  215. }
  216. }
  217. public bool CompletedSynchronously
  218. {
  219. get
  220. {
  221. return(completed_sync);
  222. }
  223. }
  224. public bool IsCompleted
  225. {
  226. get
  227. {
  228. return(completed);
  229. }
  230. set
  231. {
  232. completed=value;
  233. lock (this)
  234. {
  235. if (waithandle != null && value)
  236. {
  237. ((ManualResetEvent) waithandle).Set ();
  238. }
  239. }
  240. }
  241. }
  242. public Socket Socket
  243. {
  244. get
  245. {
  246. return acc_socket;
  247. }
  248. }
  249. public int Total
  250. {
  251. get
  252. {
  253. return total;
  254. }
  255. set
  256. {
  257. total = value;
  258. }
  259. }
  260. }
  261. private sealed class Worker
  262. {
  263. SocketAsyncResult result;
  264. public Worker (SocketAsyncResult ares)
  265. {
  266. this.result = ares;
  267. }
  268. public void Accept ()
  269. {
  270. Socket acc_socket = null;
  271. try
  272. {
  273. acc_socket = result.Sock.Accept ();
  274. }
  275. catch (Exception e)
  276. {
  277. result.Complete (e);
  278. return;
  279. }
  280. result.Complete (acc_socket);
  281. }
  282. public void Connect ()
  283. {
  284. try
  285. {
  286. result.Sock.Connect (result.EndPoint);
  287. result.Sock.connected = true;
  288. }
  289. catch (Exception e)
  290. {
  291. result.Complete (e);
  292. return;
  293. }
  294. result.Complete ();
  295. }
  296. #if !TARGET_JVM
  297. public void Receive ()
  298. {
  299. // Actual recv() done in the runtime
  300. result.Complete ();
  301. }
  302. #else
  303. public void Receive ()
  304. {
  305. int total = 0;
  306. try
  307. {
  308. total = result.Sock.Receive_nochecks (result.Buffer,
  309. result.Offset,
  310. result.Size,
  311. result.SockFlags);
  312. }
  313. catch (Exception e)
  314. {
  315. result.Complete (e);
  316. return;
  317. }
  318. result.Complete (total);
  319. }
  320. #endif
  321. public void ReceiveFrom ()
  322. {
  323. int total = 0;
  324. try
  325. {
  326. total = result.Sock.ReceiveFrom_nochecks (result.Buffer,
  327. result.Offset,
  328. result.Size,
  329. result.SockFlags,
  330. ref result.EndPoint);
  331. }
  332. catch (Exception e)
  333. {
  334. result.Complete (e);
  335. return;
  336. }
  337. result.Complete (total);
  338. }
  339. int send_so_far;
  340. void UpdateSendValues (int last_sent)
  341. {
  342. if (result.error == 0)
  343. {
  344. send_so_far += last_sent;
  345. result.Offset += last_sent;
  346. result.Size -= last_sent;
  347. }
  348. }
  349. #if !TARGET_JVM
  350. public void Send ()
  351. {
  352. // Actual send() done in the runtime
  353. if (result.error == 0)
  354. {
  355. UpdateSendValues (result.Total);
  356. if (result.Sock.disposed)
  357. {
  358. result.Complete ();
  359. return;
  360. }
  361. if (result.Size > 0)
  362. {
  363. SocketAsyncCall sac = new SocketAsyncCall (this.Send);
  364. sac.BeginInvoke (null, result);
  365. return; // Have to finish writing everything. See bug #74475.
  366. }
  367. result.Total = send_so_far;
  368. }
  369. result.Complete ();
  370. }
  371. #else
  372. public void Send ()
  373. {
  374. int total = 0;
  375. try
  376. {
  377. total = result.Sock.Send_nochecks (result.Buffer,
  378. result.Offset,
  379. result.Size,
  380. result.SockFlags);
  381. UpdateSendValues (total);
  382. if (result.Size > 0)
  383. {
  384. SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
  385. sac.BeginInvoke (null, result);
  386. return; // Have to finish writing everything. See bug #74475.
  387. }
  388. result.Total = send_so_far;
  389. }
  390. catch (Exception e)
  391. {
  392. result.Complete (e);
  393. return;
  394. }
  395. result.Complete ();
  396. }
  397. #endif
  398. public void SendTo ()
  399. {
  400. int total = 0;
  401. try
  402. {
  403. total = result.Sock.SendTo_nochecks (result.Buffer,
  404. result.Offset,
  405. result.Size,
  406. result.SockFlags,
  407. result.EndPoint);
  408. UpdateSendValues (total);
  409. if (result.Size > 0)
  410. {
  411. SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
  412. sac.BeginInvoke (null, result);
  413. return; // Have to finish writing everything. See bug #74475.
  414. }
  415. result.Total = send_so_far;
  416. }
  417. catch (Exception e)
  418. {
  419. result.Complete (e);
  420. return;
  421. }
  422. result.Complete ();
  423. }
  424. }
  425. /* the field "socket" is looked up by name by the runtime */
  426. #if !TARGET_JVM
  427. private IntPtr socket;
  428. #else
  429. private GHSocket socket;
  430. #endif
  431. private AddressFamily address_family;
  432. private SocketType socket_type;
  433. private ProtocolType protocol_type;
  434. internal bool blocking=true;
  435. private Queue readQ = new Queue (2);
  436. private Queue writeQ = new Queue (2);
  437. delegate void SocketAsyncCall ();
  438. /*
  439. * These two fields are looked up by name by the runtime, don't change
  440. * their name without also updating the runtime code.
  441. */
  442. private static int ipv4Supported = -1, ipv6Supported = -1;
  443. /* When true, the socket was connected at the time of
  444. * the last IO operation
  445. */
  446. private bool connected=false;
  447. /* true if we called Close_internal */
  448. private bool closed;
  449. internal bool disposed;
  450. /* Used in LocalEndPoint and RemoteEndPoint if the
  451. * Mono.Posix assembly is available
  452. */
  453. private static object unixendpoint=null;
  454. private static Type unixendpointtype=null;
  455. static void AddSockets (ArrayList sockets, IList list, string name)
  456. {
  457. if (list != null)
  458. {
  459. foreach (Socket sock in list)
  460. {
  461. if (sock == null) // MS throws a NullRef
  462. throw new ArgumentNullException (name, "Contains a null element");
  463. sockets.Add (sock);
  464. }
  465. }
  466. sockets.Add (null);
  467. }
  468. #if !TARGET_JVM
  469. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  470. private extern static void Select_internal (ref Socket [] sockets,
  471. int microSeconds,
  472. out int error);
  473. #else
  474. private static void Select_internal (ref Socket [] sockets, int microSeconds, out int error)
  475. {
  476. GHSocketFactory.Select_internal(ref sockets, microSeconds, out error);
  477. }
  478. #endif
  479. public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
  480. {
  481. ArrayList list = new ArrayList ();
  482. AddSockets (list, checkRead, "checkRead");
  483. AddSockets (list, checkWrite, "checkWrite");
  484. AddSockets (list, checkError, "checkError");
  485. if (list.Count == 3)
  486. {
  487. throw new ArgumentNullException ("checkRead, checkWrite, checkError",
  488. "All the lists are null or empty.");
  489. }
  490. int error;
  491. /*
  492. * The 'sockets' array contains: READ socket 0-n, null,
  493. * WRITE socket 0-n, null,
  494. * ERROR socket 0-n, null
  495. */
  496. Socket [] sockets = (Socket []) list.ToArray (typeof (Socket));
  497. Select_internal (ref sockets, microSeconds, out error);
  498. if (error != 0)
  499. throw new SocketException (error);
  500. if (checkRead != null)
  501. checkRead.Clear ();
  502. if (checkWrite != null)
  503. checkWrite.Clear ();
  504. if (checkError != null)
  505. checkError.Clear ();
  506. if (sockets == null)
  507. return;
  508. int mode = 0;
  509. int count = sockets.Length;
  510. IList currentList = checkRead;
  511. for (int i = 0; i < count; i++)
  512. {
  513. Socket sock = sockets [i];
  514. if (sock == null)
  515. { // separator
  516. currentList = (mode == 0) ? checkWrite : checkError;
  517. mode++;
  518. continue;
  519. }
  520. if (currentList != null)
  521. {
  522. sock.connected = true;
  523. currentList.Add (sock);
  524. }
  525. }
  526. }
  527. #if !TARGET_JVM
  528. static Socket()
  529. {
  530. Assembly ass;
  531. try {
  532. ass = Assembly.Load (Consts.AssemblyMono_Posix);
  533. } catch (FileNotFoundException) {
  534. return;
  535. }
  536. unixendpointtype=ass.GetType("Mono.Posix.UnixEndPoint");
  537. /* The endpoint Create() method is an instance
  538. * method :-(
  539. */
  540. Type[] arg_types=new Type[1];
  541. arg_types[0]=typeof(string);
  542. ConstructorInfo cons=unixendpointtype.GetConstructor(arg_types);
  543. object[] args=new object[1];
  544. args[0]="";
  545. unixendpoint=cons.Invoke(args);
  546. }
  547. #endif
  548. #if !TARGET_JVM
  549. // private constructor used by Accept, which already
  550. // has a socket handle to use
  551. private Socket(AddressFamily family, SocketType type,
  552. ProtocolType proto, IntPtr sock)
  553. #else
  554. // private constructor used by Accept, which already
  555. // has a socket handle to use
  556. private Socket(AddressFamily family, SocketType type,
  557. ProtocolType proto, GHSocket sock)
  558. {
  559. #endif
  560. address_family=family;
  561. socket_type=type;
  562. protocol_type=proto;
  563. socket=sock;
  564. connected=true;
  565. }
  566. #if !TARGET_JVM
  567. // Creates a new system socket, returning the handle
  568. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  569. private extern IntPtr Socket_internal(AddressFamily family,
  570. SocketType type,
  571. ProtocolType proto,
  572. out int error);
  573. #else
  574. private GHSocket Socket_internal(AddressFamily family,
  575. SocketType type,
  576. ProtocolType proto,
  577. out int error)
  578. {
  579. return GHSocketFactory.Socket_internal(family, type, proto, out error);
  580. }
  581. #endif
  582. public Socket(AddressFamily family, SocketType type,
  583. ProtocolType proto)
  584. {
  585. address_family=family;
  586. socket_type=type;
  587. protocol_type=proto;
  588. int error;
  589. socket=Socket_internal(family, type, proto, out error);
  590. if (error != 0) {
  591. throw new SocketException (error);
  592. }
  593. }
  594. public AddressFamily AddressFamily
  595. {
  596. get
  597. {
  598. return(address_family);
  599. }
  600. }
  601. #if !TARGET_JVM
  602. // Returns the amount of data waiting to be read on socket
  603. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  604. private extern static int Available_internal(IntPtr socket,
  605. out int error);
  606. #else
  607. private int Available_internal(GHSocket socket, out int error)
  608. {
  609. return socket.Available_internal(out error);
  610. }
  611. #endif
  612. public int Available
  613. {
  614. get
  615. {
  616. EnsureStillUsable();
  617. int ret, error;
  618. ret = Available_internal(socket, out error);
  619. if (error != 0)
  620. {
  621. throw new SocketException (error);
  622. }
  623. return(ret);
  624. }
  625. }
  626. #if !TARGET_JVM
  627. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  628. private extern static void Blocking_internal(IntPtr socket,
  629. bool block,
  630. out int error);
  631. #else
  632. private void Blocking_internal(GHSocket socket, bool block, out int error)
  633. {
  634. socket.Blocking_internal(block, out error);
  635. }
  636. #endif
  637. public bool Blocking
  638. {
  639. get
  640. {
  641. return(blocking);
  642. }
  643. set
  644. {
  645. EnsureStillUsable();
  646. int error;
  647. Blocking_internal(socket, value, out error);
  648. if (error != 0) {
  649. throw new SocketException (error);
  650. }
  651. blocking=value;
  652. }
  653. }
  654. public bool Connected
  655. {
  656. get
  657. {
  658. return(connected);
  659. }
  660. }
  661. #if !TARGET_JVM
  662. public IntPtr Handle
  663. {
  664. get
  665. {
  666. return(socket);
  667. }
  668. }
  669. #else
  670. public IntPtr Handle
  671. {
  672. get
  673. {
  674. throw new NotImplementedException ();
  675. }
  676. }
  677. internal GHSocket GHHandle
  678. {
  679. get
  680. {
  681. return socket;
  682. }
  683. }
  684. #endif
  685. #if !TARGET_JVM
  686. // Returns the local endpoint details in addr and port
  687. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  688. private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, out int error);
  689. [MonoTODO("Support non-IP endpoints")]
  690. public EndPoint LocalEndPoint
  691. {
  692. get
  693. {
  694. if (disposed && closed)
  695. throw new ObjectDisposedException (GetType ().ToString ());
  696. SocketAddress sa;
  697. int error;
  698. sa=LocalEndPoint_internal(socket, out error);
  699. if (error != 0) {
  700. throw new SocketException (error);
  701. }
  702. if(sa.Family==AddressFamily.InterNetwork || sa.Family==AddressFamily.InterNetworkV6) {
  703. // Stupidly, EndPoint.Create() is an
  704. // instance method
  705. return new IPEndPoint(0, 0).Create(sa);
  706. } else if (sa.Family==AddressFamily.Unix &&
  707. unixendpoint!=null) {
  708. return((EndPoint)unixendpointtype.InvokeMember("Create", BindingFlags.InvokeMethod|BindingFlags.Instance|BindingFlags.Public, null, unixendpoint, new object[] {sa}));
  709. } else {
  710. throw new NotImplementedException();
  711. }
  712. }
  713. }
  714. #else
  715. private EndPoint LocalEndPoint_internal(GHSocket socket, out int error)
  716. {
  717. return socket.LocalEndPoint_internal(out error);
  718. }
  719. public EndPoint LocalEndPoint
  720. {
  721. get
  722. {
  723. EnsureStillUsable();
  724. int error;
  725. EndPoint ret = LocalEndPoint_internal(socket, out error);
  726. if (error != 0)
  727. {
  728. throw new SocketException (error);
  729. }
  730. return ret;
  731. }
  732. }
  733. #endif
  734. public ProtocolType ProtocolType
  735. {
  736. get
  737. {
  738. return(protocol_type);
  739. }
  740. }
  741. #if !TARGET_JVM
  742. // Returns the remote endpoint details in addr and port
  743. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  744. private extern static SocketAddress RemoteEndPoint_internal(IntPtr socket, out int error);
  745. [MonoTODO("Support non-IP endpoints")]
  746. public EndPoint RemoteEndPoint
  747. {
  748. get
  749. {
  750. if (disposed && closed)
  751. throw new ObjectDisposedException (GetType ().ToString ());
  752. SocketAddress sa;
  753. int error;
  754. sa=RemoteEndPoint_internal(socket, out error);
  755. if (error != 0) {
  756. throw new SocketException (error);
  757. }
  758. if(sa.Family==AddressFamily.InterNetwork || sa.Family==AddressFamily.InterNetworkV6 ) {
  759. // Stupidly, EndPoint.Create() is an
  760. // instance method
  761. return new IPEndPoint(0, 0).Create(sa);
  762. } else if (sa.Family==AddressFamily.Unix &&
  763. unixendpoint!=null) {
  764. return((EndPoint)unixendpointtype.InvokeMember("Create", BindingFlags.InvokeMethod|BindingFlags.Instance|BindingFlags.Public, null, unixendpoint, new object[] {sa}));
  765. } else {
  766. throw new NotImplementedException();
  767. }
  768. }
  769. }
  770. #else
  771. private EndPoint RemoteEndPoint_internal(GHSocket socket, out int error)
  772. {
  773. return socket.RemoteEndPoint_internal(out error);
  774. }
  775. public EndPoint RemoteEndPoint
  776. {
  777. get
  778. {
  779. EnsureStillUsable();
  780. int error;
  781. EndPoint ret = RemoteEndPoint_internal(socket, out error);
  782. if (error != 0)
  783. {
  784. throw new SocketException (error);
  785. }
  786. return ret;
  787. }
  788. }
  789. #endif
  790. public SocketType SocketType
  791. {
  792. get
  793. {
  794. return(socket_type);
  795. }
  796. }
  797. public static bool SupportsIPv4
  798. {
  799. get
  800. {
  801. CheckProtocolSupport();
  802. return ipv4Supported == 1;
  803. }
  804. }
  805. public static bool SupportsIPv6
  806. {
  807. get
  808. {
  809. CheckProtocolSupport();
  810. return ipv6Supported == 1;
  811. }
  812. }
  813. internal static void CheckProtocolSupport()
  814. {
  815. if(ipv4Supported == -1)
  816. {
  817. try
  818. {
  819. Socket tmp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  820. tmp.Close();
  821. ipv4Supported = 1;
  822. }
  823. catch
  824. {
  825. ipv4Supported = 0;
  826. }
  827. }
  828. if(ipv6Supported == -1)
  829. {
  830. #if CONFIGURATION_DEP
  831. SettingsSection config;
  832. config = (SettingsSection) System.Configuration.ConfigurationManager.GetSection ("system.net/settings");
  833. if (config != null)
  834. ipv6Supported = config.Ipv6.Enabled ? -1 : 0;
  835. #else
  836. NetConfig config = (NetConfig)System.Configuration.ConfigurationSettings.GetConfig("system.net/settings");
  837. if(config != null)
  838. ipv6Supported = config.ipv6Enabled?-1:0;
  839. #endif
  840. if(ipv6Supported != 0)
  841. {
  842. try
  843. {
  844. Socket tmp = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
  845. tmp.Close();
  846. ipv6Supported = 1;
  847. }
  848. catch { }
  849. }
  850. }
  851. }
  852. #if !TARGET_JVM
  853. // Creates a new system socket, returning the handle
  854. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  855. private extern static IntPtr Accept_internal(IntPtr sock,
  856. out int error);
  857. #else
  858. private GHSocket Accept_internal(GHSocket sock, out int error)
  859. {
  860. return sock.Accept_internal(out error);
  861. }
  862. #endif
  863. public Socket Accept()
  864. {
  865. EnsureStillUsable();
  866. int error = 0;
  867. #if !TARGET_JVM
  868. IntPtr sock = (IntPtr) (-1);
  869. #else
  870. GHSocket sock = null;
  871. #endif
  872. sock = Accept_internal(socket, out error);
  873. if (error != 0) {
  874. throw new SocketException (error);
  875. }
  876. Socket accepted = new Socket(this.AddressFamily,
  877. this.SocketType,
  878. this.ProtocolType, sock);
  879. accepted.Blocking = this.Blocking;
  880. return(accepted);
  881. }
  882. public IAsyncResult BeginAccept(AsyncCallback callback,
  883. object state)
  884. {
  885. EnsureStillUsable();
  886. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
  887. Worker worker = new Worker (req);
  888. SocketAsyncCall sac = new SocketAsyncCall (worker.Accept);
  889. sac.BeginInvoke (null, req);
  890. return(req);
  891. }
  892. public IAsyncResult BeginConnect(EndPoint end_point,
  893. AsyncCallback callback,
  894. object state)
  895. {
  896. EnsureStillUsable();
  897. if (end_point == null)
  898. throw new ArgumentNullException ("end_point");
  899. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
  900. req.EndPoint = end_point;
  901. // Bug #75154: Connect() should not succeed for .Any addresses.
  902. if (end_point is IPEndPoint)
  903. {
  904. IPEndPoint ep = (IPEndPoint) end_point;
  905. if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any))
  906. {
  907. req.Complete (new SocketException (10049), true);
  908. return req;
  909. }
  910. }
  911. int error = 0;
  912. if (!blocking)
  913. {
  914. #if !TARGET_JVM
  915. SocketAddress serial = end_point.Serialize ();
  916. Connect_internal (socket, serial, out error);
  917. #else
  918. Connect_internal (socket, end_point, out error);
  919. #endif
  920. if (error == 0)
  921. {
  922. // succeeded synch
  923. connected = true;
  924. req.Complete (true);
  925. }
  926. else if (error != 10036 && error != 10035)
  927. {
  928. // error synch
  929. connected = false;
  930. req.Complete (new SocketException (error), true);
  931. }
  932. }
  933. if (blocking || error == 10036 || error == 10035)
  934. {
  935. // continue asynch
  936. connected = false;
  937. Worker worker = new Worker (req);
  938. SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
  939. sac.BeginInvoke (null, req);
  940. }
  941. return(req);
  942. }
  943. public IAsyncResult BeginReceive(byte[] buffer, int offset,
  944. int size,
  945. SocketFlags socket_flags,
  946. AsyncCallback callback,
  947. object state)
  948. {
  949. EnsureStillUsable();
  950. if (buffer == null)
  951. throw new ArgumentNullException ("buffer");
  952. if (offset < 0 || offset > buffer.Length)
  953. throw new ArgumentOutOfRangeException ("offset");
  954. if (size < 0 || offset + size > buffer.Length)
  955. throw new ArgumentOutOfRangeException ("size");
  956. SocketAsyncResult req;
  957. lock (readQ)
  958. {
  959. req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
  960. req.Buffer = buffer;
  961. req.Offset = offset;
  962. req.Size = size;
  963. req.SockFlags = socket_flags;
  964. readQ.Enqueue (req);
  965. if (readQ.Count == 1)
  966. {
  967. Worker worker = new Worker (req);
  968. SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
  969. sac.BeginInvoke (null, req);
  970. }
  971. }
  972. return req;
  973. }
  974. public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
  975. int size,
  976. SocketFlags socket_flags,
  977. ref EndPoint remote_end,
  978. AsyncCallback callback,
  979. object state)
  980. {
  981. EnsureStillUsable();
  982. if (buffer == null)
  983. throw new ArgumentNullException ("buffer");
  984. if (offset < 0)
  985. throw new ArgumentOutOfRangeException ("offset must be >= 0");
  986. if (size < 0)
  987. throw new ArgumentOutOfRangeException ("size must be >= 0");
  988. if (offset + size > buffer.Length)
  989. throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
  990. SocketAsyncResult req;
  991. lock (readQ)
  992. {
  993. req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
  994. req.Buffer = buffer;
  995. req.Offset = offset;
  996. req.Size = size;
  997. req.SockFlags = socket_flags;
  998. req.EndPoint = remote_end;
  999. readQ.Enqueue (req);
  1000. if (readQ.Count == 1)
  1001. {
  1002. Worker worker = new Worker (req);
  1003. SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
  1004. sac.BeginInvoke (null, req);
  1005. }
  1006. }
  1007. return req;
  1008. }
  1009. public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
  1010. AsyncCallback callback, object state)
  1011. {
  1012. EnsureStillUsable();
  1013. if (buffer == null)
  1014. throw new ArgumentNullException ("buffer");
  1015. if (offset < 0)
  1016. throw new ArgumentOutOfRangeException ("offset must be >= 0");
  1017. if (size < 0)
  1018. throw new ArgumentOutOfRangeException ("size must be >= 0");
  1019. if (offset + size > buffer.Length)
  1020. throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
  1021. SocketAsyncResult req;
  1022. lock (writeQ)
  1023. {
  1024. req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
  1025. req.Buffer = buffer;
  1026. req.Offset = offset;
  1027. req.Size = size;
  1028. req.SockFlags = socket_flags;
  1029. writeQ.Enqueue (req);
  1030. if (writeQ.Count == 1)
  1031. {
  1032. Worker worker = new Worker (req);
  1033. SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
  1034. sac.BeginInvoke (null, req);
  1035. }
  1036. }
  1037. return req;
  1038. }
  1039. public IAsyncResult BeginSendTo(byte[] buffer, int offset,
  1040. int size,
  1041. SocketFlags socket_flags,
  1042. EndPoint remote_end,
  1043. AsyncCallback callback,
  1044. object state)
  1045. {
  1046. EnsureStillUsable();
  1047. if (buffer == null)
  1048. throw new ArgumentNullException ("buffer");
  1049. if (offset < 0)
  1050. throw new ArgumentOutOfRangeException ("offset must be >= 0");
  1051. if (size < 0)
  1052. throw new ArgumentOutOfRangeException ("size must be >= 0");
  1053. if (offset + size > buffer.Length)
  1054. throw new ArgumentOutOfRangeException ("offset + size exceeds the buffer length");
  1055. SocketAsyncResult req;
  1056. lock (writeQ)
  1057. {
  1058. req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
  1059. req.Buffer = buffer;
  1060. req.Offset = offset;
  1061. req.Size = size;
  1062. req.SockFlags = socket_flags;
  1063. req.EndPoint = remote_end;
  1064. writeQ.Enqueue (req);
  1065. if (writeQ.Count == 1)
  1066. {
  1067. Worker worker = new Worker (req);
  1068. SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
  1069. sac.BeginInvoke (null, req);
  1070. }
  1071. }
  1072. return req;
  1073. }
  1074. #if !TARGET_JVM
  1075. // Creates a new system socket, returning the handle
  1076. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1077. private extern static void Bind_internal(IntPtr sock,
  1078. SocketAddress sa,
  1079. out int error);
  1080. public void Bind(EndPoint local_end)
  1081. {
  1082. if (disposed && closed)
  1083. throw new ObjectDisposedException (GetType ().ToString ());
  1084. if(local_end==null) {
  1085. throw new ArgumentNullException("local_end");
  1086. }
  1087. int error;
  1088. Bind_internal(socket, local_end.Serialize(),
  1089. out error);
  1090. if (error != 0) {
  1091. throw new SocketException (error);
  1092. }
  1093. }
  1094. #else
  1095. private void Bind_internal(GHSocket sock,
  1096. EndPoint sa,
  1097. out int error)
  1098. {
  1099. sock.Bind_internal(sa, out error);
  1100. }
  1101. public void Bind(EndPoint local_end)
  1102. {
  1103. EnsureStillUsable();
  1104. if(local_end==null) {
  1105. throw new ArgumentNullException("local_end");
  1106. }
  1107. int error;
  1108. Bind_internal(socket, local_end,
  1109. out error);
  1110. if (error != 0) {
  1111. throw new SocketException (error);
  1112. }
  1113. }
  1114. #endif
  1115. #if !TARGET_JVM
  1116. // Closes the socket
  1117. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1118. private extern static void Close_internal(IntPtr socket,
  1119. out int error);
  1120. #else
  1121. private void Close_internal(GHSocket socket, out int error)
  1122. {
  1123. socket.Close_internal(out error);
  1124. }
  1125. #endif
  1126. public void Close()
  1127. {
  1128. ((IDisposable) this).Dispose ();
  1129. }
  1130. #if !TARGET_JVM
  1131. // Connects to the remote address
  1132. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1133. private extern static void Connect_internal(IntPtr sock,
  1134. SocketAddress sa,
  1135. out int error);
  1136. #else
  1137. private void Connect_internal(GHSocket sock,
  1138. EndPoint sa,
  1139. out int error)
  1140. {
  1141. sock.Connect_internal(sa, out error);
  1142. }
  1143. #endif
  1144. public void Connect(EndPoint remote_end)
  1145. {
  1146. EnsureStillUsable();
  1147. if(remote_end==null) {
  1148. throw new ArgumentNullException("remote_end");
  1149. }
  1150. if (remote_end is IPEndPoint) {
  1151. IPEndPoint ep = (IPEndPoint) remote_end;
  1152. if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any))
  1153. throw new SocketException (10049);
  1154. }
  1155. int error = 0;
  1156. #if !TARGET_JVM
  1157. Connect_internal (socket, remote_end.Serialize(), out error);
  1158. #else
  1159. Connect_internal (socket, remote_end, out error);
  1160. #endif
  1161. if (error != 0) {
  1162. throw new SocketException (error);
  1163. }
  1164. connected=true;
  1165. }
  1166. #if TARGET_JVM
  1167. public void ChangeToSSL()
  1168. {
  1169. try
  1170. {
  1171. GHSocket tmp = socket.ChangeToSSL(null);
  1172. if (tmp != null)
  1173. {
  1174. socket = tmp;
  1175. }
  1176. }
  1177. catch (Exception e)
  1178. {
  1179. #if DEBUG
  1180. Console.WriteLine("Caught exception during ChangeToSSL: {0}, {1}", e.GetType(), e.Message);
  1181. #endif
  1182. throw new SocketException(10045);
  1183. }
  1184. }
  1185. #endif
  1186. public Socket EndAccept(IAsyncResult result)
  1187. {
  1188. EnsureStillUsable();
  1189. if (result == null)
  1190. throw new ArgumentNullException ("result");
  1191. SocketAsyncResult req = result as SocketAsyncResult;
  1192. if (req == null)
  1193. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1194. if (!result.IsCompleted)
  1195. result.AsyncWaitHandle.WaitOne();
  1196. req.CheckIfThrowDelayedException();
  1197. return req.Socket;
  1198. }
  1199. public void EndConnect(IAsyncResult result) {
  1200. EnsureStillUsable();
  1201. if (result == null)
  1202. throw new ArgumentNullException ("result");
  1203. SocketAsyncResult req = result as SocketAsyncResult;
  1204. if (req == null)
  1205. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1206. if (!result.IsCompleted)
  1207. result.AsyncWaitHandle.WaitOne();
  1208. req.CheckIfThrowDelayedException();
  1209. }
  1210. [MonoNotSupported ("")]
  1211. public void EndDisconnect (IAsyncResult asyncResult)
  1212. {
  1213. throw new NotImplementedException ();
  1214. }
  1215. public int EndReceive(IAsyncResult result) {
  1216. EnsureStillUsable();
  1217. if (result == null)
  1218. throw new ArgumentNullException ("result");
  1219. SocketAsyncResult req = result as SocketAsyncResult;
  1220. if (req == null)
  1221. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1222. if (!result.IsCompleted)
  1223. result.AsyncWaitHandle.WaitOne();
  1224. req.CheckIfThrowDelayedException();
  1225. return req.Total;
  1226. }
  1227. public int EndReceiveFrom(IAsyncResult result,
  1228. ref EndPoint end_point)
  1229. {
  1230. EnsureStillUsable();
  1231. if (result == null)
  1232. throw new ArgumentNullException ("result");
  1233. SocketAsyncResult req = result as SocketAsyncResult;
  1234. if (req == null)
  1235. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1236. if (!result.IsCompleted)
  1237. result.AsyncWaitHandle.WaitOne();
  1238. req.CheckIfThrowDelayedException();
  1239. end_point = req.EndPoint;
  1240. return req.Total;
  1241. }
  1242. public int EndSend(IAsyncResult result) {
  1243. EnsureStillUsable();
  1244. if (result == null)
  1245. throw new ArgumentNullException ("result");
  1246. SocketAsyncResult req = result as SocketAsyncResult;
  1247. if (req == null)
  1248. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1249. if (!result.IsCompleted)
  1250. result.AsyncWaitHandle.WaitOne();
  1251. req.CheckIfThrowDelayedException();
  1252. return req.Total;
  1253. }
  1254. public int EndSendTo(IAsyncResult result) {
  1255. EnsureStillUsable();
  1256. if (result == null)
  1257. throw new ArgumentNullException ("result");
  1258. SocketAsyncResult req = result as SocketAsyncResult;
  1259. if (req == null)
  1260. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1261. if (!result.IsCompleted)
  1262. result.AsyncWaitHandle.WaitOne();
  1263. req.CheckIfThrowDelayedException();
  1264. return req.Total;
  1265. }
  1266. #if !TARGET_JVM
  1267. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1268. private extern static void GetSocketOption_obj_internal(IntPtr socket, SocketOptionLevel level, SocketOptionName name, out object obj_val, out int error);
  1269. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1270. private extern static void GetSocketOption_arr_internal(IntPtr socket, SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val, out int error);
  1271. #else
  1272. private void GetSocketOption_obj_internal(GHSocket socket, SocketOptionLevel level,
  1273. SocketOptionName name, out object obj_val, out int error)
  1274. {
  1275. EnsureStillUsable();
  1276. socket.GetSocketOption_obj_internal(level, name, out obj_val, out error);
  1277. }
  1278. private void GetSocketOption_arr_internal(GHSocket socket, SocketOptionLevel level,
  1279. SocketOptionName name, ref byte[] byte_val, out int error)
  1280. {
  1281. EnsureStillUsable();
  1282. socket.GetSocketOption_arr_internal(level, name, ref byte_val, out error);
  1283. }
  1284. #endif
  1285. public object GetSocketOption(SocketOptionLevel level,
  1286. SocketOptionName name) {
  1287. object obj_val;
  1288. int error;
  1289. GetSocketOption_obj_internal(socket, level, name,
  1290. out obj_val, out error);
  1291. if (error != 0) {
  1292. throw new SocketException (error);
  1293. }
  1294. if(name==SocketOptionName.Linger) {
  1295. return((LingerOption)obj_val);
  1296. } else if (name==SocketOptionName.AddMembership ||
  1297. name==SocketOptionName.DropMembership) {
  1298. return((MulticastOption)obj_val);
  1299. } else if (obj_val is int) {
  1300. return((int)obj_val);
  1301. } else {
  1302. return(obj_val);
  1303. }
  1304. }
  1305. public void GetSocketOption(SocketOptionLevel level,
  1306. SocketOptionName name,
  1307. byte[] opt_value) {
  1308. int error;
  1309. GetSocketOption_arr_internal(socket, level, name,
  1310. ref opt_value, out error);
  1311. if (error != 0) {
  1312. throw new SocketException (error);
  1313. }
  1314. }
  1315. public byte[] GetSocketOption(SocketOptionLevel level,
  1316. SocketOptionName name,
  1317. int length) {
  1318. byte[] byte_val=new byte[length];
  1319. int error;
  1320. GetSocketOption_arr_internal(socket, level, name,
  1321. ref byte_val, out error);
  1322. if (error != 0) {
  1323. throw new SocketException (error);
  1324. }
  1325. return(byte_val);
  1326. }
  1327. #if !TARGET_JVM
  1328. // See Socket.IOControl, WSAIoctl documentation in MSDN. The
  1329. // common options between UNIX and Winsock are FIONREAD,
  1330. // FIONBIO and SIOCATMARK. Anything else will depend on the
  1331. // system.
  1332. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1333. extern static int WSAIoctl (IntPtr sock, int ioctl_code,
  1334. byte [] input, byte [] output,
  1335. out int error);
  1336. #else
  1337. int WSAIoctl (GHSocket sock, int ioctl_code,
  1338. byte [] input, byte [] output,
  1339. out int error)
  1340. {
  1341. return sock.WSAIoctl(ioctl_code, input, output, out error);
  1342. }
  1343. #endif
  1344. public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
  1345. {
  1346. if (disposed)
  1347. throw new ObjectDisposedException (GetType ().ToString ());
  1348. int error;
  1349. int result = WSAIoctl (socket, ioctl_code, in_value,
  1350. out_value, out error);
  1351. if (error != 0) {
  1352. throw new SocketException (error);
  1353. }
  1354. if (result == -1)
  1355. throw new InvalidOperationException ("Must use Blocking property instead.");
  1356. return result;
  1357. }
  1358. [MonoNotSupported ("")]
  1359. public int IOControl (IOControlCode ioControlCode, byte [] optionInValue, byte [] optionOutValue)
  1360. {
  1361. throw new NotImplementedException ();
  1362. }
  1363. #if !TARGET_JVM
  1364. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1365. private extern static void Listen_internal(IntPtr sock,
  1366. int backlog,
  1367. out int error);
  1368. #else
  1369. private void Listen_internal(GHSocket sock,
  1370. int backlog,
  1371. out int error)
  1372. {
  1373. EnsureStillUsable();
  1374. sock.Listen_internal(backlog, out error);
  1375. }
  1376. #endif
  1377. public void Listen(int backlog)
  1378. {
  1379. int error;
  1380. Listen_internal(socket, backlog, out error);
  1381. if (error != 0) {
  1382. throw new SocketException (error);
  1383. }
  1384. }
  1385. #if !TARGET_JVM
  1386. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1387. extern static bool Poll_internal (IntPtr socket, SelectMode mode, int timeout, out int error);
  1388. #else
  1389. bool Poll_internal (GHSocket socket, SelectMode mode, int timeout, out int error)
  1390. {
  1391. return socket.Poll_internal(mode, timeout, this, out error);
  1392. }
  1393. #endif
  1394. public bool Poll(int time_us, SelectMode mode)
  1395. {
  1396. EnsureStillUsable();
  1397. if (mode != SelectMode.SelectRead &&
  1398. mode != SelectMode.SelectWrite &&
  1399. mode != SelectMode.SelectError)
  1400. throw new NotSupportedException ("'mode' parameter is not valid.");
  1401. int error;
  1402. bool result = Poll_internal (socket, mode, time_us, out error);
  1403. if (error != 0)
  1404. throw new SocketException (error);
  1405. if (result == true) {
  1406. /* Update the connected state; for
  1407. * non-blocking Connect()s this is
  1408. * when we can find out that the
  1409. * connect succeeded.
  1410. */
  1411. connected = true;
  1412. }
  1413. return result;
  1414. }
  1415. public int Receive (byte [] buf)
  1416. {
  1417. EnsureStillUsable();
  1418. if (buf == null)
  1419. throw new ArgumentNullException ("buf");
  1420. return Receive_nochecks (buf, 0, buf.Length, SocketFlags.None);
  1421. }
  1422. public int Receive (byte [] buf, SocketFlags flags)
  1423. {
  1424. EnsureStillUsable();
  1425. if (buf == null)
  1426. throw new ArgumentNullException ("buf");
  1427. return Receive_nochecks (buf, 0, buf.Length, flags);
  1428. }
  1429. public int Receive (byte [] buf, int size, SocketFlags flags)
  1430. {
  1431. EnsureStillUsable();
  1432. if (buf == null)
  1433. throw new ArgumentNullException ("buf");
  1434. if (size < 0 || size > buf.Length)
  1435. throw new ArgumentOutOfRangeException ("size");
  1436. return Receive_nochecks (buf, 0, size, flags);
  1437. }
  1438. #if !TARGET_JVM
  1439. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1440. private extern static int Receive_internal(IntPtr sock,
  1441. byte[] buffer,
  1442. int offset,
  1443. int count,
  1444. SocketFlags flags,
  1445. out int error);
  1446. #else
  1447. private int Receive_internal(GHSocket sock,
  1448. byte[] buffer,
  1449. int offset,
  1450. int count,
  1451. SocketFlags flags,
  1452. out int error)
  1453. {
  1454. return sock.Receive_internal(buffer, offset, count, flags, out error);
  1455. }
  1456. #endif
  1457. public int Receive (byte [] buf, int offset, int size, SocketFlags flags)
  1458. {
  1459. EnsureStillUsable();
  1460. if(buf==null)
  1461. throw new ArgumentNullException ("buf");
  1462. if (offset < 0 || offset > buf.Length)
  1463. throw new ArgumentOutOfRangeException ("offset");
  1464. if (size < 0 || offset + size > buf.Length)
  1465. throw new ArgumentOutOfRangeException ("size");
  1466. return Receive_nochecks (buf, offset, size, flags);
  1467. }
  1468. int Receive_nochecks (byte [] buf, int offset, int size, SocketFlags flags)
  1469. {
  1470. int ret, error;
  1471. ret = Receive_internal (socket, buf, offset, size, flags, out error);
  1472. if(error != 0) {
  1473. if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
  1474. connected=false;
  1475. throw new SocketException (error);
  1476. }
  1477. connected=true;
  1478. return ret;
  1479. }
  1480. public int ReceiveFrom (byte [] buf, ref EndPoint remote_end)
  1481. {
  1482. if (buf == null)
  1483. throw new ArgumentNullException ("buf");
  1484. if (remote_end == null)
  1485. throw new ArgumentNullException ("remote_end");
  1486. return ReceiveFrom_nochecks (buf, 0, buf.Length, SocketFlags.None, ref remote_end);
  1487. }
  1488. public int ReceiveFrom (byte [] buf, SocketFlags flags, ref EndPoint remote_end)
  1489. {
  1490. if (buf == null)
  1491. throw new ArgumentNullException ("buf");
  1492. if (remote_end == null)
  1493. throw new ArgumentNullException ("remote_end");
  1494. return ReceiveFrom_nochecks (buf, 0, buf.Length, flags, ref remote_end);
  1495. }
  1496. public int ReceiveFrom(byte[] buf, int size, SocketFlags flags,
  1497. ref EndPoint remote_end)
  1498. {
  1499. if (buf == null)
  1500. throw new ArgumentNullException ("buf");
  1501. if (remote_end == null)
  1502. throw new ArgumentNullException ("remote_end");
  1503. if (size < 0 || size > buf.Length)
  1504. throw new ArgumentOutOfRangeException ("size");
  1505. return ReceiveFrom_nochecks (buf, 0, size, flags, ref remote_end);
  1506. }
  1507. #if !TARGET_JVM
  1508. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1509. private extern static int RecvFrom_internal(IntPtr sock,
  1510. byte[] buffer,
  1511. int offset,
  1512. int count,
  1513. SocketFlags flags,
  1514. ref SocketAddress sockaddr,
  1515. out int error);
  1516. #else
  1517. private int RecvFrom_internal(GHSocket sock,
  1518. byte[] buffer,
  1519. int offset,
  1520. int count,
  1521. SocketFlags flags,
  1522. ref SocketAddress sockaddr,
  1523. out int error)
  1524. {
  1525. return sock.RecvFrom_internal(buffer, offset, count, flags, ref sockaddr, out error);
  1526. }
  1527. #endif
  1528. public int ReceiveFrom(byte[] buf, int offset, int size, SocketFlags flags,
  1529. ref EndPoint remote_end)
  1530. {
  1531. EnsureStillUsable();
  1532. if (buf == null)
  1533. throw new ArgumentNullException ("buf");
  1534. if (remote_end == null)
  1535. throw new ArgumentNullException ("remote_end");
  1536. if (offset < 0 || offset > buf.Length)
  1537. throw new ArgumentOutOfRangeException ("offset");
  1538. if (size < 0 || offset + size > buf.Length)
  1539. throw new ArgumentOutOfRangeException ("size");
  1540. return ReceiveFrom_nochecks (buf, offset, size, flags, ref remote_end);
  1541. }
  1542. int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
  1543. ref EndPoint remote_end)
  1544. {
  1545. EnsureStillUsable();
  1546. SocketAddress sockaddr=remote_end.Serialize();
  1547. int cnt, error;
  1548. cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
  1549. if (error != 0) {
  1550. if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
  1551. connected=false;
  1552. throw new SocketException (error);
  1553. }
  1554. connected=true;
  1555. // If sockaddr is null then we're a connection
  1556. // oriented protocol and should ignore the
  1557. // remote_end parameter (see MSDN
  1558. // documentation for Socket.ReceiveFrom(...) )
  1559. if ( sockaddr != null ) {
  1560. // Stupidly, EndPoint.Create() is an
  1561. // instance method
  1562. remote_end=remote_end.Create(sockaddr);
  1563. }
  1564. return cnt;
  1565. }
  1566. public int Send (byte [] buf)
  1567. {
  1568. EnsureStillUsable();
  1569. if (buf == null)
  1570. throw new ArgumentNullException ("buf");
  1571. return Send_nochecks (buf, 0, buf.Length, SocketFlags.None);
  1572. }
  1573. public int Send (byte [] buf, SocketFlags flags)
  1574. {
  1575. EnsureStillUsable();
  1576. if (buf == null)
  1577. throw new ArgumentNullException ("buf");
  1578. return Send_nochecks (buf, 0, buf.Length, flags);
  1579. }
  1580. public int Send (byte [] buf, int size, SocketFlags flags)
  1581. {
  1582. EnsureStillUsable();
  1583. if (buf == null)
  1584. throw new ArgumentNullException ("buf");
  1585. if (size < 0 || size > buf.Length)
  1586. throw new ArgumentOutOfRangeException ("size");
  1587. return Send_nochecks (buf, 0, size, flags);
  1588. }
  1589. [MonoNotSupported ("")]
  1590. public int Send (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode)
  1591. {
  1592. throw new NotImplementedException ();
  1593. }
  1594. [MonoNotSupported ("")]
  1595. public int Send (IList<ArraySegment<byte>> buffers)
  1596. {
  1597. throw new NotImplementedException ();
  1598. }
  1599. [MonoNotSupported ("")]
  1600. public int Send (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags)
  1601. {
  1602. throw new NotImplementedException ();
  1603. }
  1604. //[CLSCompliantAttribute (false)]
  1605. [MonoNotSupported ("")]
  1606. public int Send (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode)
  1607. {
  1608. throw new NotImplementedException ();
  1609. }
  1610. [MonoNotSupported ("")]
  1611. public int Receive (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode)
  1612. {
  1613. throw new NotImplementedException ();
  1614. }
  1615. [MonoNotSupported ("")]
  1616. public int Receive (IList<ArraySegment<byte>> buffers)
  1617. {
  1618. throw new NotImplementedException ();
  1619. }
  1620. //[CLSCompliantAttribute (false)]
  1621. [MonoNotSupported ("")]
  1622. public int Receive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags)
  1623. {
  1624. throw new NotImplementedException ();
  1625. }
  1626. //[CLSCompliantAttribute (false)]
  1627. [MonoNotSupported ("")]
  1628. public int Receive (IList<ArraySegment<byte>> buffers, SocketFlags socketFlags, out SocketError errorCode)
  1629. {
  1630. throw new NotImplementedException ();
  1631. }
  1632. [MonoNotSupported ("")]
  1633. public int ReceiveMessageFrom (byte [] buffer, int offset, int size, ref SocketFlags socketFlags, ref EndPoint remoteEP, out IPPacketInformation ipPacketInformation)
  1634. {
  1635. throw new NotImplementedException ();
  1636. }
  1637. [MonoNotSupported ("")]
  1638. public IAsyncResult BeginReceiveMessageFrom (byte [] buffer, int offset, int size, SocketFlags socketFlags, ref EndPoint remoteEP, AsyncCallback callback, Object state)
  1639. {
  1640. throw new NotImplementedException ();
  1641. }
  1642. [MonoNotSupported ("")]
  1643. public int EndReceiveMessageFrom (IAsyncResult asyncResult, ref SocketFlags socketFlags, ref EndPoint endPoint, out IPPacketInformation ipPacketInformation)
  1644. {
  1645. throw new NotImplementedException ();
  1646. }
  1647. #if !TARGET_JVM
  1648. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1649. private extern static int Send_internal(IntPtr sock,
  1650. byte[] buf, int offset,
  1651. int count,
  1652. SocketFlags flags,
  1653. out int error);
  1654. #else
  1655. private int Send_internal(GHSocket sock,
  1656. byte[] buf, int offset,
  1657. int count,
  1658. SocketFlags flags,
  1659. out int error)
  1660. {
  1661. return sock.Send_internal(buf, offset, count, flags, out error);
  1662. }
  1663. #endif
  1664. public int Send (byte[] buf, int offset, int size, SocketFlags flags)
  1665. {
  1666. EnsureStillUsable();
  1667. if (buf == null)
  1668. throw new ArgumentNullException ("buffer");
  1669. if (offset < 0 || offset > buf.Length)
  1670. throw new ArgumentOutOfRangeException ("offset");
  1671. if (size < 0 || offset + size > buf.Length)
  1672. throw new ArgumentOutOfRangeException ("size");
  1673. return Send_nochecks (buf, offset, size, flags);
  1674. }
  1675. int Send_nochecks (byte [] buf, int offset, int size, SocketFlags flags)
  1676. {
  1677. if (size == 0)
  1678. return 0;
  1679. int ret, error;
  1680. ret = Send_internal (socket, buf, offset, size, flags, out error);
  1681. if (error != 0) {
  1682. if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
  1683. connected = false;
  1684. throw new SocketException (error);
  1685. }
  1686. connected = true;
  1687. return ret;
  1688. }
  1689. public int SendTo (byte [] buffer, EndPoint remote_end)
  1690. {
  1691. EnsureStillUsable();
  1692. if (buffer == null)
  1693. throw new ArgumentNullException ("buffer");
  1694. if (remote_end == null)
  1695. throw new ArgumentNullException ("remote_end");
  1696. return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
  1697. }
  1698. public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
  1699. {
  1700. EnsureStillUsable();
  1701. if (buffer == null)
  1702. throw new ArgumentNullException ("buffer");
  1703. if (remote_end == null)
  1704. throw new ArgumentNullException ("remote_end");
  1705. return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
  1706. }
  1707. public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
  1708. {
  1709. EnsureStillUsable();
  1710. if (buffer == null)
  1711. throw new ArgumentNullException ("buffer");
  1712. if (remote_end == null)
  1713. throw new ArgumentNullException ("remote_end");
  1714. if (size < 0 || size > buffer.Length)
  1715. throw new ArgumentOutOfRangeException ("size");
  1716. return SendTo_nochecks (buffer, 0, size, flags, remote_end);
  1717. }
  1718. #if !TARGET_JVM
  1719. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1720. private extern static int SendTo_internal(IntPtr sock,
  1721. byte[] buffer,
  1722. int offset,
  1723. int count,
  1724. SocketFlags flags,
  1725. SocketAddress sa,
  1726. out int error);
  1727. #else
  1728. private int SendTo_internal(GHSocket sock,
  1729. byte[] buffer,
  1730. int offset,
  1731. int count,
  1732. SocketFlags flags,
  1733. SocketAddress sa,
  1734. out int error)
  1735. {
  1736. return sock.SendTo_internal(buffer, offset, count, flags, sa, out error);
  1737. }
  1738. #endif
  1739. public int SendTo(byte[] buffer, int offset, int size, SocketFlags flags,
  1740. EndPoint remote_end)
  1741. {
  1742. EnsureStillUsable();
  1743. if (buffer == null)
  1744. throw new ArgumentNullException ("buffer");
  1745. if (remote_end == null)
  1746. throw new ArgumentNullException("remote_end");
  1747. if (offset < 0 || offset > buffer.Length)
  1748. throw new ArgumentOutOfRangeException ("offset");
  1749. if (size < 0 || offset + size > buffer.Length)
  1750. throw new ArgumentOutOfRangeException ("size");
  1751. return SendTo_nochecks (buffer, offset, size, flags, remote_end);
  1752. }
  1753. int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
  1754. EndPoint remote_end)
  1755. {
  1756. SocketAddress sockaddr=remote_end.Serialize();
  1757. int ret, error;
  1758. ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
  1759. if (error != 0) {
  1760. if (error != 10035 && error != 10036) // WSAEWOULDBLOCK …

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