PageRenderTime 109ms CodeModel.GetById 44ms RepoModel.GetById 6ms 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
  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, SelectMode.SelectWrite);
  1566. error = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
  1567. if (error == 0) {
  1568. connected = true;
  1569. seed_endpoint = iep;
  1570. return;
  1571. }
  1572. }
  1573. }
  1574. if (error != 0)
  1575. throw new SocketException (error);
  1576. }
  1577. public void Connect (string host, int port)
  1578. {
  1579. IPAddress [] addresses = Dns.GetHostAddresses (host);
  1580. Connect (addresses, port);
  1581. }
  1582. #if NET_2_0
  1583. public bool DisconnectAsync (SocketAsyncEventArgs e)
  1584. {
  1585. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  1586. if (disposed && closed)
  1587. throw new ObjectDisposedException (GetType ().ToString ());
  1588. e.DoOperation (SocketAsyncOperation.Disconnect, this);
  1589. return true;
  1590. }
  1591. #endif
  1592. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1593. private extern static void Disconnect_internal(IntPtr sock,
  1594. bool reuse,
  1595. out int error);
  1596. /* According to the docs, the MS runtime will throw
  1597. * PlatformNotSupportedException if the platform is
  1598. * newer than w2k. We should be able to cope...
  1599. */
  1600. public void Disconnect (bool reuseSocket)
  1601. {
  1602. if (disposed && closed)
  1603. throw new ObjectDisposedException (GetType ().ToString ());
  1604. int error = 0;
  1605. Disconnect_internal (socket, reuseSocket, out error);
  1606. if (error != 0) {
  1607. if (error == 50) {
  1608. /* ERROR_NOT_SUPPORTED */
  1609. throw new PlatformNotSupportedException ();
  1610. } else {
  1611. throw new SocketException (error);
  1612. }
  1613. }
  1614. connected = false;
  1615. if (reuseSocket) {
  1616. /* Do managed housekeeping here... */
  1617. }
  1618. }
  1619. [MonoTODO ("Not implemented")]
  1620. public SocketInformation DuplicateAndClose (int targetProcessId)
  1621. {
  1622. /* Need to serialize this socket into a
  1623. * SocketInformation struct, but must study
  1624. * the MS implementation harder to figure out
  1625. * behaviour as documentation is lacking
  1626. */
  1627. throw new NotImplementedException ();
  1628. }
  1629. #endif
  1630. public Socket EndAccept (IAsyncResult result)
  1631. {
  1632. int bytes;
  1633. byte[] buffer;
  1634. return(EndAccept (out buffer, out bytes, result));
  1635. }
  1636. #if NET_2_0
  1637. public Socket EndAccept (out byte[] buffer,
  1638. IAsyncResult asyncResult)
  1639. {
  1640. int bytes;
  1641. return(EndAccept (out buffer, out bytes, asyncResult));
  1642. }
  1643. #endif
  1644. #if NET_2_0
  1645. public
  1646. #else
  1647. private
  1648. #endif
  1649. Socket EndAccept (out byte[] buffer, out int bytesTransferred,
  1650. IAsyncResult asyncResult)
  1651. {
  1652. if (disposed && closed)
  1653. throw new ObjectDisposedException (GetType ().ToString ());
  1654. if (asyncResult == null)
  1655. throw new ArgumentNullException ("asyncResult");
  1656. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  1657. if (req == null)
  1658. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  1659. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1660. throw InvalidAsyncOp ("EndAccept");
  1661. if (!asyncResult.IsCompleted)
  1662. asyncResult.AsyncWaitHandle.WaitOne ();
  1663. req.CheckIfThrowDelayedException ();
  1664. buffer = req.Buffer;
  1665. bytesTransferred = req.Total;
  1666. return(req.Socket);
  1667. }
  1668. public void EndConnect (IAsyncResult result)
  1669. {
  1670. if (disposed && closed)
  1671. throw new ObjectDisposedException (GetType ().ToString ());
  1672. if (result == null)
  1673. throw new ArgumentNullException ("result");
  1674. SocketAsyncResult req = result as SocketAsyncResult;
  1675. if (req == null)
  1676. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1677. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1678. throw InvalidAsyncOp ("EndConnect");
  1679. if (!result.IsCompleted)
  1680. result.AsyncWaitHandle.WaitOne();
  1681. req.CheckIfThrowDelayedException();
  1682. }
  1683. #if NET_2_0
  1684. public void EndDisconnect (IAsyncResult asyncResult)
  1685. {
  1686. if (disposed && closed)
  1687. throw new ObjectDisposedException (GetType ().ToString ());
  1688. if (asyncResult == null)
  1689. throw new ArgumentNullException ("asyncResult");
  1690. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  1691. if (req == null)
  1692. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  1693. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1694. throw InvalidAsyncOp ("EndDisconnect");
  1695. if (!asyncResult.IsCompleted)
  1696. asyncResult.AsyncWaitHandle.WaitOne ();
  1697. req.CheckIfThrowDelayedException ();
  1698. }
  1699. #endif
  1700. public int EndReceive (IAsyncResult result)
  1701. {
  1702. SocketError error;
  1703. return (EndReceive (result, out error));
  1704. }
  1705. #if NET_2_0
  1706. public
  1707. #else
  1708. private
  1709. #endif
  1710. int EndReceive (IAsyncResult asyncResult, out SocketError errorCode)
  1711. {
  1712. if (disposed && closed)
  1713. throw new ObjectDisposedException (GetType ().ToString ());
  1714. if (asyncResult == null)
  1715. throw new ArgumentNullException ("asyncResult");
  1716. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  1717. if (req == null)
  1718. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  1719. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1720. throw InvalidAsyncOp ("EndReceive");
  1721. if (!asyncResult.IsCompleted)
  1722. asyncResult.AsyncWaitHandle.WaitOne ();
  1723. errorCode = req.ErrorCode;
  1724. req.CheckIfThrowDelayedException ();
  1725. return(req.Total);
  1726. }
  1727. public int EndReceiveFrom(IAsyncResult result, ref EndPoint end_point)
  1728. {
  1729. if (disposed && closed)
  1730. throw new ObjectDisposedException (GetType ().ToString ());
  1731. if (result == null)
  1732. throw new ArgumentNullException ("result");
  1733. SocketAsyncResult req = result as SocketAsyncResult;
  1734. if (req == null)
  1735. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1736. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1737. throw InvalidAsyncOp ("EndReceiveFrom");
  1738. if (!result.IsCompleted)
  1739. result.AsyncWaitHandle.WaitOne();
  1740. req.CheckIfThrowDelayedException();
  1741. end_point = req.EndPoint;
  1742. return req.Total;
  1743. }
  1744. #if NET_2_0
  1745. [MonoTODO]
  1746. public int EndReceiveMessageFrom (IAsyncResult asyncResult,
  1747. ref SocketFlags socketFlags,
  1748. ref EndPoint endPoint,
  1749. out IPPacketInformation ipPacketInformation)
  1750. {
  1751. if (disposed && closed)
  1752. throw new ObjectDisposedException (GetType ().ToString ());
  1753. if (asyncResult == null)
  1754. throw new ArgumentNullException ("asyncResult");
  1755. if (endPoint == null)
  1756. throw new ArgumentNullException ("endPoint");
  1757. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  1758. if (req == null)
  1759. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  1760. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1761. throw InvalidAsyncOp ("EndReceiveMessageFrom");
  1762. throw new NotImplementedException ();
  1763. }
  1764. #endif
  1765. public int EndSend (IAsyncResult result)
  1766. {
  1767. SocketError error;
  1768. return(EndSend (result, out error));
  1769. }
  1770. #if NET_2_0
  1771. public
  1772. #else
  1773. private
  1774. #endif
  1775. int EndSend (IAsyncResult asyncResult, out SocketError errorCode)
  1776. {
  1777. if (disposed && closed)
  1778. throw new ObjectDisposedException (GetType ().ToString ());
  1779. if (asyncResult == null)
  1780. throw new ArgumentNullException ("asyncResult");
  1781. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  1782. if (req == null)
  1783. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1784. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1785. throw InvalidAsyncOp ("EndSend");
  1786. if (!asyncResult.IsCompleted)
  1787. asyncResult.AsyncWaitHandle.WaitOne ();
  1788. errorCode = req.ErrorCode;
  1789. req.CheckIfThrowDelayedException ();
  1790. return(req.Total);
  1791. }
  1792. #if NET_2_0
  1793. public void EndSendFile (IAsyncResult asyncResult)
  1794. {
  1795. if (disposed && closed)
  1796. throw new ObjectDisposedException (GetType ().ToString ());
  1797. if (asyncResult == null)
  1798. throw new ArgumentNullException ("asyncResult");
  1799. SendFileAsyncResult ares = asyncResult as SendFileAsyncResult;
  1800. if (ares == null)
  1801. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  1802. ares.Delegate.EndInvoke (ares.Original);
  1803. }
  1804. #endif
  1805. Exception InvalidAsyncOp (string method)
  1806. {
  1807. return new InvalidOperationException (method + " can only be called once per asynchronous operation");
  1808. }
  1809. public int EndSendTo (IAsyncResult result)
  1810. {
  1811. if (disposed && closed)
  1812. throw new ObjectDisposedException (GetType ().ToString ());
  1813. if (result == null)
  1814. throw new ArgumentNullException ("result");
  1815. SocketAsyncResult req = result as SocketAsyncResult;
  1816. if (req == null)
  1817. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1818. if (Interlocked.CompareExchange (ref req.EndCalled, 1, 0) == 1)
  1819. throw InvalidAsyncOp ("EndSendTo");
  1820. if (!result.IsCompleted)
  1821. result.AsyncWaitHandle.WaitOne();
  1822. req.CheckIfThrowDelayedException();
  1823. return req.Total;
  1824. }
  1825. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1826. private extern static void GetSocketOption_arr_internal(IntPtr socket,
  1827. SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val,
  1828. out int error);
  1829. public void GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
  1830. {
  1831. if (disposed && closed)
  1832. throw new ObjectDisposedException (GetType ().ToString ());
  1833. if (optionValue == null)
  1834. throw new SocketException ((int) SocketError.Fault,
  1835. "Error trying to dereference an invalid pointer");
  1836. int error;
  1837. GetSocketOption_arr_internal (socket, optionLevel, optionName, ref optionValue,
  1838. out error);
  1839. if (error != 0)
  1840. throw new SocketException (error);
  1841. }
  1842. public byte [] GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, int length)
  1843. {
  1844. if (disposed && closed)
  1845. throw new ObjectDisposedException (GetType ().ToString ());
  1846. byte[] byte_val=new byte[length];
  1847. int error;
  1848. GetSocketOption_arr_internal (socket, optionLevel, optionName, ref byte_val,
  1849. out error);
  1850. if (error != 0)
  1851. throw new SocketException (error);
  1852. return(byte_val);
  1853. }
  1854. // See Socket.IOControl, WSAIoctl documentation in MSDN. The
  1855. // common options between UNIX and Winsock are FIONREAD,
  1856. // FIONBIO and SIOCATMARK. Anything else will depend on the
  1857. // system.
  1858. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1859. extern static int WSAIoctl (IntPtr sock, int ioctl_code, byte [] input,
  1860. byte [] output, out int error);
  1861. public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
  1862. {
  1863. if (disposed)
  1864. throw new ObjectDisposedException (GetType ().ToString ());
  1865. int error;
  1866. int result = WSAIoctl (socket, ioctl_code, in_value, out_value,
  1867. out error);
  1868. if (error != 0)
  1869. throw new SocketException (error);
  1870. if (result == -1)
  1871. throw new InvalidOperationException ("Must use Blocking property instead.");
  1872. return result;
  1873. }
  1874. #if NET_2_0
  1875. [MonoTODO]
  1876. public int IOControl (IOControlCode ioControlCode,
  1877. byte[] optionInValue,
  1878. byte[] optionOutValue)
  1879. {
  1880. /* Probably just needs to mirror the int
  1881. * overload, but more investigation needed.
  1882. */
  1883. throw new NotImplementedException ();
  1884. }
  1885. #endif
  1886. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1887. private extern static void Listen_internal(IntPtr sock, int backlog,
  1888. out int error);
  1889. public void Listen (int backlog)
  1890. {
  1891. if (disposed && closed)
  1892. throw new ObjectDisposedException (GetType ().ToString ());
  1893. #if NET_2_0
  1894. /* TODO: check if this should be thrown in the
  1895. * 1.1 profile too
  1896. */
  1897. if (!isbound)
  1898. throw new SocketException ((int)SocketError.InvalidArgument);
  1899. #endif
  1900. int error;
  1901. Listen_internal(socket, backlog, out error);
  1902. if (error != 0)
  1903. throw new SocketException (error);
  1904. #if NET_2_0
  1905. islistening = true;
  1906. #endif
  1907. }
  1908. public bool Poll (int time_us, SelectMode mode)
  1909. {
  1910. if (disposed && closed)
  1911. throw new ObjectDisposedException (GetType ().ToString ());
  1912. if (mode != SelectMode.SelectRead &&
  1913. mode != SelectMode.SelectWrite &&
  1914. mode != SelectMode.SelectError)
  1915. throw new NotSupportedException ("'mode' parameter is not valid.");
  1916. int error;
  1917. bool result = Poll_internal (socket, mode, time_us, out error);
  1918. if (error != 0)
  1919. throw new SocketException (error);
  1920. if (mode == SelectMode.SelectWrite && result && !connected) {
  1921. /* Update the connected state; for
  1922. * non-blocking Connect()s this is
  1923. * when we can find out that the
  1924. * connect succeeded.
  1925. */
  1926. if ((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
  1927. connected = true;
  1928. }
  1929. }
  1930. return result;
  1931. }
  1932. public int Receive (byte [] buffer)
  1933. {
  1934. if (disposed && closed)
  1935. throw new ObjectDisposedException (GetType ().ToString ());
  1936. if (buffer == null)
  1937. throw new ArgumentNullException ("buffer");
  1938. SocketError error;
  1939. int ret = Receive_nochecks (buffer, 0, buffer.Length, SocketFlags.None, out error);
  1940. if (error != SocketError.Success)
  1941. throw new SocketException ((int) error);
  1942. return ret;
  1943. }
  1944. public int Receive (byte [] buffer, SocketFlags flags)
  1945. {
  1946. if (disposed && closed)
  1947. throw new ObjectDisposedException (GetType ().ToString ());
  1948. if (buffer == null)
  1949. throw new ArgumentNullException ("buffer");
  1950. SocketError error;
  1951. int ret = Receive_nochecks (buffer, 0, buffer.Length, flags, out error);
  1952. if (error != SocketError.Success) {
  1953. if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
  1954. throw new SocketException ((int) error, "Operation timed out.");
  1955. throw new SocketException ((int) error);
  1956. }
  1957. return ret;
  1958. }
  1959. public int Receive (byte [] buffer, int size, SocketFlags flags)
  1960. {
  1961. if (disposed && closed)
  1962. throw new ObjectDisposedException (GetType ().ToString ());
  1963. if (buffer == null)
  1964. throw new ArgumentNullException ("buffer");
  1965. if (size < 0 || size > buffer.Length)
  1966. throw new ArgumentOutOfRangeException ("size");
  1967. SocketError error;
  1968. int ret = Receive_nochecks (buffer, 0, size, flags, out error);
  1969. if (error != SocketError.Success) {
  1970. if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
  1971. throw new SocketException ((int) error, "Operation timed out.");
  1972. throw new SocketException ((int) error);
  1973. }
  1974. return ret;
  1975. }
  1976. public int Receive (byte [] buffer, int offset, int size, SocketFlags flags)
  1977. {
  1978. if (disposed && closed)
  1979. throw new ObjectDisposedException (GetType ().ToString ());
  1980. if (buffer == null)
  1981. throw new ArgumentNullException ("buffer");
  1982. if (offset < 0 || offset > buffer.Length)
  1983. throw new ArgumentOutOfRangeException ("offset");
  1984. if (size < 0 || offset + size > buffer.Length)
  1985. throw new ArgumentOutOfRangeException ("size");
  1986. SocketError error;
  1987. int ret = Receive_nochecks (buffer, offset, size, flags, out error);
  1988. if (error != SocketError.Success) {
  1989. if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
  1990. throw new SocketException ((int) error, "Operation timed out.");
  1991. throw new SocketException ((int) error);
  1992. }
  1993. return ret;
  1994. }
  1995. #if NET_2_0
  1996. public int Receive (byte [] buffer, int offset, int size, SocketFlags flags, out SocketError error)
  1997. {
  1998. if (disposed && closed)
  1999. throw new ObjectDisposedException (GetType ().ToString ());
  2000. if (buffer == null)
  2001. throw new ArgumentNullException ("buffer");
  2002. if (offset < 0 || offset > buffer.Length)
  2003. throw new ArgumentOutOfRangeException ("offset");
  2004. if (size < 0 || offset + size > buffer.Length)
  2005. throw new ArgumentOutOfRangeException ("size");
  2006. return Receive_nochecks (buffer, offset, size, flags, out error);
  2007. }
  2008. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  2009. private extern static int Receive_internal (IntPtr sock,
  2010. WSABUF[] bufarray,
  2011. SocketFlags flags,
  2012. out int error);
  2013. public int Receive (IList<ArraySegment<byte>> buffers)
  2014. {
  2015. int ret;
  2016. SocketError error;
  2017. ret = Receive (buffers, SocketFlags.None, out error);
  2018. if (error != SocketError.Success) {
  2019. throw new SocketException ((int)error);
  2020. }
  2021. return(ret);
  2022. }
  2023. [CLSCompliant (false)]
  2024. public int Receive (IList<ArraySegment<byte>> buffers,
  2025. SocketFlags socketFlags)
  2026. {
  2027. int ret;
  2028. SocketError error;
  2029. ret = Receive (buffers, socketFlags, out error);
  2030. if (error != SocketError.Success) {
  2031. throw new SocketException ((int)error);
  2032. }
  2033. return(ret);
  2034. }
  2035. [CLSCompliant (false)]
  2036. public int Receive (IList<ArraySegment<byte>> buffers,
  2037. SocketFlags socketFlags,
  2038. out SocketError errorCode)
  2039. {
  2040. if (disposed && closed)
  2041. throw new ObjectDisposedException (GetType ().ToString ());
  2042. if (buffers == null ||
  2043. buffers.Count == 0) {
  2044. throw new ArgumentNullException ("buffers");
  2045. }
  2046. int numsegments = buffers.Count;
  2047. int nativeError;
  2048. int ret;
  2049. /* Only example I can find of sending a byte
  2050. * array reference directly into an internal
  2051. * call is in
  2052. * System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeSocket.cs,
  2053. * so taking a lead from that...
  2054. */
  2055. WSABUF[] bufarray = new WSABUF[numsegments];
  2056. GCHandle[] gch = new GCHandle[numsegments];
  2057. for(int i = 0; i < numsegments; i++) {
  2058. ArraySegment<byte> segment = buffers[i];
  2059. gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
  2060. bufarray[i].len = segment.Count;
  2061. bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
  2062. }
  2063. try {
  2064. ret = Receive_internal (socket, bufarray,
  2065. socketFlags,
  2066. out nativeError);
  2067. } finally {
  2068. for(int i = 0; i < numsegments; i++) {
  2069. if (gch[i].IsAllocated) {
  2070. gch[i].Free ();
  2071. }
  2072. }
  2073. }
  2074. errorCode = (SocketError)nativeError;
  2075. return(ret);
  2076. }
  2077. #endif
  2078. #if NET_2_0
  2079. public bool ReceiveFromAsync (SocketAsyncEventArgs e)
  2080. {
  2081. if (disposed && closed)
  2082. throw new ObjectDisposedException (GetType ().ToString ());
  2083. // We do not support recv into multiple buffers yet
  2084. if (e.BufferList != null)
  2085. throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
  2086. if (e.RemoteEndPoint == null)
  2087. throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
  2088. e.DoOperation (SocketAsyncOperation.ReceiveFrom, this);
  2089. // We always return true for now
  2090. return true;
  2091. }
  2092. #endif
  2093. public int ReceiveFrom (byte [] buffer, ref EndPoint remoteEP)
  2094. {
  2095. if (disposed && closed)
  2096. throw new ObjectDisposedException (GetType ().ToString ());
  2097. if (buffer == null)
  2098. throw new ArgumentNullException ("buffer");
  2099. if (remoteEP == null)
  2100. throw new ArgumentNullException ("remoteEP");
  2101. return ReceiveFrom_nochecks (buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP);
  2102. }
  2103. public int ReceiveFrom (byte [] buffer, SocketFlags flags, ref EndPoint remoteEP)
  2104. {
  2105. if (disposed && closed)
  2106. throw new ObjectDisposedException (GetType ().ToString ());
  2107. if (buffer == null)
  2108. throw new ArgumentNullException ("buffer");
  2109. if (remoteEP == null)
  2110. throw new ArgumentNullException ("remoteEP");
  2111. return ReceiveFrom_nochecks (buffer, 0, buffer.Length, flags, ref remoteEP);
  2112. }
  2113. public int ReceiveFrom (byte [] buffer, int size, SocketFlags flags,
  2114. ref EndPoint remoteEP)
  2115. {
  2116. if (disposed && closed)
  2117. throw new ObjectDisposedException (GetType ().ToString ());
  2118. if (buffer == null)
  2119. throw new ArgumentNullException ("buffer");
  2120. if (remoteEP == null)
  2121. throw new ArgumentNullException ("remoteEP");
  2122. if (size < 0 || size > buffer.Length)
  2123. throw new ArgumentOutOfRangeException ("size");
  2124. return ReceiveFrom_nochecks (buffer, 0, size, flags, ref remoteEP);
  2125. }
  2126. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2127. private extern static int RecvFrom_internal(IntPtr sock,
  2128. byte[] buffer,
  2129. int offset,
  2130. int count,
  2131. SocketFlags flags,
  2132. ref SocketAddress sockaddr,
  2133. out int error);
  2134. public int ReceiveFrom (byte [] buffer, int offset, int size, SocketFlags flags,
  2135. ref EndPoint remoteEP)
  2136. {
  2137. if (disposed && closed)
  2138. throw new ObjectDisposedException (GetType ().ToString ());
  2139. if (buffer == null)
  2140. throw new ArgumentNullException ("buffer");
  2141. if (remoteEP == null)
  2142. throw new ArgumentNullException ("remoteEP");
  2143. if (offset < 0 || offset > buffer.Length)
  2144. throw new ArgumentOutOfRangeException ("offset");
  2145. if (size < 0 || offset + size > buffer.Length)
  2146. throw new ArgumentOutOfRangeException ("size");
  2147. return ReceiveFrom_nochecks (buffer, offset, size, flags, ref remoteEP);
  2148. }
  2149. internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
  2150. ref EndPoint remote_end)
  2151. {
  2152. int error;
  2153. return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
  2154. }
  2155. internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags,
  2156. ref EndPoint remote_end, bool throwOnError, out int error)
  2157. {
  2158. SocketAddress sockaddr = remote_end.Serialize();
  2159. int cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
  2160. SocketError err = (SocketError) error;
  2161. if (err != 0) {
  2162. if (err != SocketError.WouldBlock && err != SocketError.InProgress)
  2163. connected = false;
  2164. else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
  2165. if (throwOnError)
  2166. throw new SocketException ((int) SocketError.TimedOut, "Operation timed out");
  2167. error = (int) SocketError.TimedOut;
  2168. return 0;
  2169. }
  2170. if (throwOnError)
  2171. throw new SocketException (error);
  2172. return 0;
  2173. }
  2174. connected = true;
  2175. #if NET_2_0
  2176. isbound = true;
  2177. #endif
  2178. // If sockaddr is null then we're a connection
  2179. // oriented protocol and should ignore the
  2180. // remote_end parameter (see MSDN
  2181. // documentation for Socket.ReceiveFrom(...) )
  2182. if ( sockaddr != null ) {
  2183. // Stupidly, EndPoint.Create() is an
  2184. // instance method
  2185. remote_end = remote_end.Create (sockaddr);
  2186. }
  2187. seed_endpoint = remote_end;
  2188. return cnt;
  2189. }
  2190. #if NET_2_0
  2191. [MonoTODO ("Not implemented")]
  2192. public bool ReceiveMessageFromAsync (SocketAsyncEventArgs e)
  2193. {
  2194. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  2195. if (disposed && closed)
  2196. throw new ObjectDisposedException (GetType ().ToString ());
  2197. throw new NotImplementedException ();
  2198. }
  2199. [MonoTODO ("Not implemented")]
  2200. public int ReceiveMessageFrom (byte[] buffer, int offset,
  2201. int size,
  2202. ref SocketFlags socketFlags,
  2203. ref EndPoint remoteEP,
  2204. out IPPacketInformation ipPacketInformation)
  2205. {
  2206. if (disposed && closed)
  2207. throw new ObjectDisposedException (GetType ().ToString ());
  2208. if (buffer == null)
  2209. throw new ArgumentNullException ("buffer");
  2210. if (remoteEP == null)
  2211. throw new ArgumentNullException ("remoteEP");
  2212. if (offset < 0 || offset > buffer.Length)
  2213. throw new ArgumentOutOfRangeException ("offset");
  2214. if (size < 0 || offset + size > buffer.Length)
  2215. throw new ArgumentOutOfRangeException ("size");
  2216. /* FIXME: figure out how we get hold of the
  2217. * IPPacketInformation
  2218. */
  2219. throw new NotImplementedException ();
  2220. }
  2221. [MonoTODO ("Not implemented")]
  2222. public bool SendPacketsAsync (SocketAsyncEventArgs e)
  2223. {
  2224. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  2225. if (disposed && closed)
  2226. throw new ObjectDisposedException (GetType ().ToString ());
  2227. throw new NotImplementedException ();
  2228. }
  2229. #endif
  2230. public int Send (byte [] buf)
  2231. {
  2232. if (disposed && closed)
  2233. throw new ObjectDisposedException (GetType ().ToString ());
  2234. if (buf == null)
  2235. throw new ArgumentNullException ("buf");
  2236. SocketError error;
  2237. int ret = Send_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
  2238. if (error != SocketError.Success)
  2239. throw new SocketException ((int) error);
  2240. return ret;
  2241. }
  2242. public int Send (byte [] buf, SocketFlags flags)
  2243. {
  2244. if (disposed && closed)
  2245. throw new ObjectDisposedException (GetType ().ToString ());
  2246. if (buf == null)
  2247. throw new ArgumentNullException ("buf");
  2248. SocketError error;
  2249. int ret = Send_nochecks (buf, 0, buf.Length, flags, out error);
  2250. if (error != SocketError.Success)
  2251. throw new SocketException ((int) error);
  2252. return ret;
  2253. }
  2254. public int Send (byte [] buf, int size, SocketFlags flags)
  2255. {
  2256. if (disposed && closed)
  2257. throw new ObjectDisposedException (GetType ().ToString ());
  2258. if (buf == null)
  2259. throw new ArgumentNullException ("buf");
  2260. if (size < 0 || size > buf.Length)
  2261. throw new ArgumentOutOfRangeException ("size");
  2262. SocketError error;
  2263. int ret = Send_nochecks (buf, 0, size, flags, out error);
  2264. if (error != SocketError.Success)
  2265. throw new SocketException ((int) error);
  2266. return ret;
  2267. }
  2268. public int Send (byte [] buf, int offset, int size, SocketFlags flags)
  2269. {
  2270. if (disposed && closed)
  2271. throw new ObjectDisposedException (GetType ().ToString ());
  2272. if (buf == null)
  2273. throw new ArgumentNullException ("buffer");
  2274. if (offset < 0 || offset > buf.Length)
  2275. throw new ArgumentOutOfRangeException ("offset");
  2276. if (size < 0 || offset + size > buf.Length)
  2277. throw new ArgumentOutOfRangeException ("size");
  2278. SocketError error;
  2279. int ret = Send_nochecks (buf, offset, size, flags, out error);
  2280. if (error != SocketError.Success)
  2281. throw new SocketException ((int) error);
  2282. return ret;
  2283. }
  2284. #if NET_2_0
  2285. public int Send (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
  2286. {
  2287. if (disposed && closed)
  2288. throw new ObjectDisposedException (GetType ().ToString ());
  2289. if (buf == null)
  2290. throw new ArgumentNullException ("buffer");
  2291. if (offset < 0 || offset > buf.Length)
  2292. throw new ArgumentOutOfRangeException ("offset");
  2293. if (size < 0 || offset + size > buf.Length)
  2294. throw new ArgumentOutOfRangeException ("size");
  2295. return Send_nochecks (buf, offset, size, flags, out error);
  2296. }
  2297. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  2298. private extern static int Send_internal (IntPtr sock,
  2299. WSABUF[] bufarray,
  2300. SocketFlags flags,
  2301. out int error);
  2302. public int Send (IList<ArraySegment<byte>> buffers)
  2303. {
  2304. int ret;
  2305. SocketError error;
  2306. ret = Send (buffers, SocketFlags.None, out error);
  2307. if (error != SocketError.Success) {
  2308. throw new SocketException ((int)error);
  2309. }
  2310. return(ret);
  2311. }
  2312. public int Send (IList<ArraySegment<byte>> buffers,
  2313. SocketFlags socketFlags)
  2314. {
  2315. int ret;
  2316. SocketError error;
  2317. ret = Send (buffers, socketFlags, out error);
  2318. if (error != SocketError.Success) {
  2319. throw new SocketException ((int)error);
  2320. }
  2321. return(ret);
  2322. }
  2323. [CLSCompliant (false)]
  2324. public int Send (IList<ArraySegment<byte>> buffers,
  2325. SocketFlags socketFlags,
  2326. out SocketError errorCode)
  2327. {
  2328. if (disposed && closed) {
  2329. throw new ObjectDisposedException (GetType ().ToString ());
  2330. }
  2331. if (buffers == null) {
  2332. throw new ArgumentNullException ("buffers");
  2333. }
  2334. if (buffers.Count == 0) {
  2335. throw new ArgumentException ("Buffer is empty", "buffers");
  2336. }
  2337. int numsegments = buffers.Count;
  2338. int nativeError;
  2339. int ret;
  2340. WSABUF[] bufarray = new WSABUF[numsegments];
  2341. GCHandle[] gch = new GCHandle[numsegments];
  2342. for(int i = 0; i < numsegments; i++) {
  2343. ArraySegment<byte> segment = buffers[i];
  2344. gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
  2345. bufarray[i].len = segment.Count;
  2346. bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
  2347. }
  2348. try {
  2349. ret = Send_internal (socket, bufarray,
  2350. socketFlags,
  2351. out nativeError);
  2352. } finally {
  2353. for(int i = 0; i < numsegments; i++) {
  2354. if (gch[i].IsAllocated) {
  2355. gch[i].Free ();
  2356. }
  2357. }
  2358. }
  2359. errorCode = (SocketError)nativeError;
  2360. return(ret);
  2361. }
  2362. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2363. private extern static bool SendFile (IntPtr sock, string filename, byte [] pre_buffer, byte [] post_buffer, TransmitFileOptions flags);
  2364. public void SendFile (string fileName)
  2365. {
  2366. if (disposed && closed)
  2367. throw new ObjectDisposedException (GetType ().ToString ());
  2368. if (!connected)
  2369. throw new NotSupportedException ();
  2370. if (!blocking)
  2371. throw new InvalidOperationException ();
  2372. SendFile (fileName, null, null, 0);
  2373. }
  2374. public void SendFile (string fileName, byte[] preBuffer, byte[] postBuffer, TransmitFileOptions flags)
  2375. {
  2376. if (disposed && closed)
  2377. throw new ObjectDisposedException (GetType ().ToString ());
  2378. if (!connected)
  2379. throw new NotSupportedException ();
  2380. if (!blocking)
  2381. throw new InvalidOperationException ();
  2382. if (!SendFile (socket, fileName, preBuffer, postBuffer, flags)) {
  2383. SocketException exc = new SocketException ();
  2384. if (exc.ErrorCode == 2 || exc.ErrorCode == 3)
  2385. throw new FileNotFoundException ();
  2386. throw exc;
  2387. }
  2388. }
  2389. public bool SendToAsync (SocketAsyncEventArgs e)
  2390. {
  2391. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  2392. if (disposed && closed)
  2393. throw new ObjectDisposedException (GetType ().ToString ());
  2394. if (e.RemoteEndPoint == null)
  2395. throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
  2396. e.DoOperation (SocketAsyncOperation.SendTo, this);
  2397. // We always return true for now
  2398. return true;
  2399. }
  2400. #endif
  2401. public int SendTo (byte [] buffer, EndPoint remote_end)
  2402. {
  2403. if (disposed && closed)
  2404. throw new ObjectDisposedException (GetType ().ToString ());
  2405. if (buffer == null)
  2406. throw new ArgumentNullException ("buffer");
  2407. if (remote_end == null)
  2408. throw new ArgumentNullException ("remote_end");
  2409. return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
  2410. }
  2411. public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
  2412. {
  2413. if (disposed && closed)
  2414. throw new ObjectDisposedException (GetType ().ToString ());
  2415. if (buffer == null)
  2416. throw new ArgumentNullException ("buffer");
  2417. if (remote_end == null)
  2418. throw new ArgumentNullException ("remote_end");
  2419. return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
  2420. }
  2421. public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
  2422. {
  2423. if (disposed && closed)
  2424. throw new ObjectDisposedException (GetType ().ToString ());
  2425. if (buffer == null)
  2426. throw new ArgumentNullException ("buffer");
  2427. if (remote_end == null)
  2428. throw new ArgumentNullException ("remote_end");
  2429. if (size < 0 || size > buffer.Length)
  2430. throw new ArgumentOutOfRangeException ("size");
  2431. return SendTo_nochecks (buffer, 0, size, flags, remote_end);
  2432. }
  2433. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2434. private extern static int SendTo_internal(IntPtr sock,
  2435. byte[] buffer,
  2436. int offset,
  2437. int count,
  2438. SocketFlags flags,
  2439. SocketAddress sa,
  2440. out int error);
  2441. public int SendTo (byte [] buffer, int offset, int size, SocketFlags flags,
  2442. EndPoint remote_end)
  2443. {
  2444. if (disposed && closed)
  2445. throw new ObjectDisposedException (GetType ().ToString ());
  2446. if (buffer == null)
  2447. throw new ArgumentNullException ("buffer");
  2448. if (remote_end == null)
  2449. throw new ArgumentNullException("remote_end");
  2450. if (offset < 0 || offset > buffer.Length)
  2451. throw new ArgumentOutOfRangeException ("offset");
  2452. if (size < 0 || offset + size > buffer.Length)
  2453. throw new ArgumentOutOfRangeException ("size");
  2454. return SendTo_nochecks (buffer, offset, size, flags, remote_end);
  2455. }
  2456. internal int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
  2457. EndPoint remote_end)
  2458. {
  2459. SocketAddress sockaddr = remote_end.Serialize ();
  2460. int ret, error;
  2461. ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
  2462. SocketError err = (SocketError) error;
  2463. if (err != 0) {
  2464. if (err != SocketError.WouldBlock && err != SocketError.InProgress)
  2465. connected = false;
  2466. throw new SocketException (error);
  2467. }
  2468. connected = true;
  2469. #if NET_2_0
  2470. isbound = true;
  2471. #endif
  2472. seed_endpoint = remote_end;
  2473. return ret;
  2474. }
  2475. public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, byte [] optionValue)
  2476. {
  2477. if (disposed && closed)
  2478. throw new ObjectDisposedException (GetType ().ToString ());
  2479. // I'd throw an ArgumentNullException, but this is what MS does.
  2480. if (optionValue == null)
  2481. throw new SocketException ((int) SocketError.Fault,
  2482. "Error trying to dereference an invalid pointer");
  2483. int error;
  2484. SetSocketOption_internal (socket, optionLevel, optionName, null,
  2485. optionValue, 0, out error);
  2486. if (error != 0) {
  2487. if (error == (int) SocketError.InvalidArgument)
  2488. throw new ArgumentException ();
  2489. throw new SocketException (error);
  2490. }
  2491. }
  2492. public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, object optionValue)
  2493. {
  2494. if (disposed && closed)
  2495. throw new ObjectDisposedException (GetType ().ToString ());
  2496. // NOTE: if a null is passed, the byte[] overload is used instead...
  2497. if (optionValue == null)
  2498. throw new ArgumentNullException("optionValue");
  2499. int error;
  2500. if (optionLevel == SocketOptionLevel.Socket && optionName == SocketOptionName.Linger) {
  2501. LingerOption linger = optionValue as LingerOption;
  2502. if (linger == null)
  2503. #if NET_2_0
  2504. throw new ArgumentException ("A 'LingerOption' value must be specified.", "optionValue");
  2505. #else
  2506. throw new ArgumentException ("optionValue");
  2507. #endif
  2508. SetSocketOption_internal (socket, optionLevel, optionName, linger, null, 0, out error);
  2509. } else if (optionLevel == SocketOptionLevel.IP && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
  2510. MulticastOption multicast = optionValue as MulticastOption;
  2511. if (multicast == null)
  2512. #if NET_2_0
  2513. throw new ArgumentException ("A 'MulticastOption' value must be specified.", "optionValue");
  2514. #else
  2515. throw new ArgumentException ("optionValue");
  2516. #endif
  2517. SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
  2518. } else if (optionLevel == SocketOptionLevel.IPv6 && (optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership)) {
  2519. IPv6MulticastOption multicast = optionValue as IPv6MulticastOption;
  2520. if (multicast == null)
  2521. #if NET_2_0
  2522. throw new ArgumentException ("A 'IPv6MulticastOption' value must be specified.", "optionValue");
  2523. #else
  2524. throw new ArgumentException ("optionValue");
  2525. #endif
  2526. SetSocketOption_internal (socket, optionLevel, optionName, multicast, null, 0, out error);
  2527. } else {
  2528. #if NET_2_0
  2529. throw new ArgumentException ("Invalid value specified.", "optionValue");
  2530. #else
  2531. throw new ArgumentException ("optionValue");
  2532. #endif
  2533. }
  2534. if (error != 0) {
  2535. if (error == (int) SocketError.InvalidArgument)
  2536. throw new ArgumentException ();
  2537. throw new SocketException (error);
  2538. }
  2539. }
  2540. #if NET_2_0
  2541. public void SetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, bool optionValue)
  2542. {
  2543. if (disposed && closed)
  2544. throw new ObjectDisposedException (GetType ().ToString ());
  2545. int error;
  2546. int int_val = (optionValue) ? 1 : 0;
  2547. SetSocketOption_internal (socket, optionLevel, optionName, null, null, int_val, out error);
  2548. if (error != 0) {
  2549. if (error == (int) SocketError.InvalidArgument)
  2550. throw new ArgumentException ();
  2551. throw new SocketException (error);
  2552. }
  2553. }
  2554. #endif
  2555. #if ONLY_1_1
  2556. public override int GetHashCode ()
  2557. {
  2558. // LAMESPEC:
  2559. // The socket is not suitable to serve as a hash code,
  2560. // because it will change during its lifetime, but
  2561. // this is how MS.NET 1.1 implemented this method.
  2562. return (int) socket;
  2563. }
  2564. #endif
  2565. }
  2566. }