Socket.cs 97 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679
  1. // System.Net.Sockets.Socket.cs
  2. //
  3. // Authors:
  4. // Phillip Pearson ([email protected])
  5. // Dick Porter <[email protected]>
  6. // Gonzalo Paniagua Javier ([email protected])
  7. // Sridhar Kulkarni ([email protected])
  8. // Brian Nickel ([email protected])
  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. #if !NET_2_1
  48. using System.Timers;
  49. #endif
  50. #endif
  51. namespace System.Net.Sockets
  52. {
  53. public class Socket : IDisposable
  54. {
  55. enum SocketOperation {
  56. Accept,
  57. Connect,
  58. Receive,
  59. ReceiveFrom,
  60. Send,
  61. SendTo,
  62. UsedInManaged1,
  63. UsedInManaged2,
  64. UsedInProcess,
  65. UsedInConsole2,
  66. Disconnect,
  67. AcceptReceive,
  68. ReceiveGeneric,
  69. SendGeneric
  70. }
  71. [StructLayout (LayoutKind.Sequential)]
  72. struct WSABUF
  73. {
  74. public int len;
  75. public IntPtr buf;
  76. };
  77. [StructLayout (LayoutKind.Sequential)]
  78. private sealed class SocketAsyncResult: IAsyncResult
  79. {
  80. /* Same structure in the runtime */
  81. /*
  82. Keep this in sync with MonoSocketAsyncResult in
  83. metadata/socket-io.h and ProcessAsyncReader
  84. in System.Diagnostics/Process.cs.
  85. */
  86. public Socket Sock;
  87. public IntPtr handle;
  88. object state;
  89. AsyncCallback callback;
  90. WaitHandle waithandle;
  91. Exception delayedException;
  92. public EndPoint EndPoint; // Connect,ReceiveFrom,SendTo
  93. public byte [] Buffer; // Receive,ReceiveFrom,Send,SendTo
  94. public int Offset; // Receive,ReceiveFrom,Send,SendTo
  95. public int Size; // Receive,ReceiveFrom,Send,SendTo
  96. public SocketFlags SockFlags; // Receive,ReceiveFrom,Send,SendTo
  97. public Socket AcceptSocket; // AcceptReceive
  98. public IPAddress[] Addresses; // Connect
  99. public int Port; // Connect
  100. #if NET_2_0
  101. public IList<ArraySegment<byte>> Buffers; // Receive, Send
  102. #else
  103. public object Buffers; // Reserve this slot in older profiles
  104. #endif
  105. public bool ReuseSocket; // Disconnect
  106. // Return values
  107. Socket acc_socket;
  108. int total;
  109. bool completed_sync;
  110. bool completed;
  111. public bool blocking;
  112. internal int error;
  113. SocketOperation operation;
  114. public object ares;
  115. public SocketAsyncResult (Socket sock, object state, AsyncCallback callback, SocketOperation operation)
  116. {
  117. this.Sock = sock;
  118. this.blocking = sock.blocking;
  119. this.handle = sock.socket;
  120. this.state = state;
  121. this.callback = callback;
  122. this.operation = operation;
  123. SockFlags = SocketFlags.None;
  124. }
  125. public void CheckIfThrowDelayedException ()
  126. {
  127. if (delayedException != null) {
  128. Sock.connected = false;
  129. throw delayedException;
  130. }
  131. if (error != 0) {
  132. Sock.connected = false;
  133. throw new SocketException (error);
  134. }
  135. }
  136. void CompleteAllOnDispose (Queue queue)
  137. {
  138. object [] pending = queue.ToArray ();
  139. queue.Clear ();
  140. WaitCallback cb;
  141. for (int i = 0; i < pending.Length; i++) {
  142. SocketAsyncResult ares = (SocketAsyncResult) pending [i];
  143. cb = new WaitCallback (ares.CompleteDisposed);
  144. ThreadPool.QueueUserWorkItem (cb, null);
  145. }
  146. if (pending.Length == 0)
  147. Buffer = null;
  148. }
  149. void CompleteDisposed (object unused)
  150. {
  151. Complete ();
  152. }
  153. public void Complete ()
  154. {
  155. if (operation != SocketOperation.Receive && Sock.disposed)
  156. delayedException = new ObjectDisposedException (Sock.GetType ().ToString ());
  157. IsCompleted = true;
  158. Queue queue = null;
  159. if (operation == SocketOperation.Receive || operation == SocketOperation.ReceiveFrom) {
  160. queue = Sock.readQ;
  161. } else if (operation == SocketOperation.Send || operation == SocketOperation.SendTo) {
  162. queue = Sock.writeQ;
  163. }
  164. if (queue != null) {
  165. SocketAsyncCall sac = null;
  166. SocketAsyncResult req = null;
  167. lock (queue) {
  168. queue.Dequeue (); // remove ourselves
  169. if (queue.Count > 0) {
  170. req = (SocketAsyncResult) queue.Peek ();
  171. if (!Sock.disposed) {
  172. Worker worker = new Worker (req);
  173. sac = GetDelegate (worker, req.operation);
  174. } else {
  175. CompleteAllOnDispose (queue);
  176. }
  177. }
  178. }
  179. if (sac != null)
  180. sac.BeginInvoke (null, req);
  181. }
  182. if (callback != null)
  183. callback (this);
  184. Buffer = null;
  185. }
  186. SocketAsyncCall GetDelegate (Worker worker, SocketOperation op)
  187. {
  188. switch (op) {
  189. case SocketOperation.Receive:
  190. return new SocketAsyncCall (worker.Receive);
  191. case SocketOperation.ReceiveFrom:
  192. return new SocketAsyncCall (worker.ReceiveFrom);
  193. case SocketOperation.Send:
  194. return new SocketAsyncCall (worker.Send);
  195. case SocketOperation.SendTo:
  196. return new SocketAsyncCall (worker.SendTo);
  197. default:
  198. return null; // never happens
  199. }
  200. }
  201. public void Complete (bool synch)
  202. {
  203. completed_sync = synch;
  204. Complete ();
  205. }
  206. public void Complete (int total)
  207. {
  208. this.total = total;
  209. Complete ();
  210. }
  211. public void Complete (Exception e, bool synch)
  212. {
  213. completed_sync = synch;
  214. delayedException = e;
  215. Complete ();
  216. }
  217. public void Complete (Exception e)
  218. {
  219. delayedException = e;
  220. Complete ();
  221. }
  222. public void Complete (Socket s)
  223. {
  224. acc_socket = s;
  225. Complete ();
  226. }
  227. public void Complete (Socket s, int total)
  228. {
  229. acc_socket = s;
  230. this.total = total;
  231. Complete ();
  232. }
  233. public object AsyncState {
  234. get {
  235. return state;
  236. }
  237. }
  238. public WaitHandle AsyncWaitHandle {
  239. get {
  240. lock (this) {
  241. if (waithandle == null)
  242. waithandle = new ManualResetEvent (completed);
  243. }
  244. return waithandle;
  245. }
  246. set {
  247. waithandle=value;
  248. }
  249. }
  250. public bool CompletedSynchronously {
  251. get {
  252. return(completed_sync);
  253. }
  254. }
  255. public bool IsCompleted {
  256. get {
  257. return(completed);
  258. }
  259. set {
  260. completed=value;
  261. lock (this) {
  262. if (waithandle != null && value) {
  263. ((ManualResetEvent) waithandle).Set ();
  264. }
  265. }
  266. }
  267. }
  268. public Socket Socket {
  269. get {
  270. return acc_socket;
  271. }
  272. }
  273. public int Total {
  274. get { return total; }
  275. set { total = value; }
  276. }
  277. public SocketError ErrorCode
  278. {
  279. get {
  280. #if NET_2_0
  281. SocketException ex = delayedException as SocketException;
  282. if (ex != null)
  283. return(ex.SocketErrorCode);
  284. if (error != 0)
  285. return((SocketError)error);
  286. #endif
  287. return(SocketError.Success);
  288. }
  289. }
  290. }
  291. private sealed class Worker
  292. {
  293. SocketAsyncResult result;
  294. public Worker (SocketAsyncResult ares)
  295. {
  296. this.result = ares;
  297. }
  298. public void Accept ()
  299. {
  300. Socket acc_socket = null;
  301. try {
  302. acc_socket = result.Sock.Accept ();
  303. } catch (Exception e) {
  304. result.Complete (e);
  305. return;
  306. }
  307. result.Complete (acc_socket);
  308. }
  309. /* only used in 2.0 profile and newer, but
  310. * leave in older profiles to keep interface
  311. * to runtime consistent
  312. */
  313. public void AcceptReceive ()
  314. {
  315. Socket acc_socket = null;
  316. try {
  317. if (result.AcceptSocket == null) {
  318. acc_socket = result.Sock.Accept ();
  319. } else {
  320. acc_socket = result.AcceptSocket;
  321. result.Sock.Accept (acc_socket);
  322. }
  323. } catch (Exception e) {
  324. result.Complete (e);
  325. return;
  326. }
  327. /* It seems the MS runtime
  328. * special-cases 0-length requested
  329. * receive data. See bug 464201.
  330. */
  331. int total = 0;
  332. if (result.Size > 0) {
  333. try {
  334. SocketError error;
  335. total = acc_socket.Receive_nochecks (result.Buffer,
  336. result.Offset,
  337. result.Size,
  338. result.SockFlags,
  339. out error);
  340. } catch (Exception e) {
  341. result.Complete (e);
  342. return;
  343. }
  344. }
  345. result.Complete (acc_socket, total);
  346. }
  347. public void Connect ()
  348. {
  349. /* If result.EndPoint is non-null,
  350. * this is the standard one-address
  351. * connect attempt. Otherwise
  352. * Addresses must be non-null and
  353. * contain a list of addresses to try
  354. * to connect to; the first one to
  355. * succeed causes the rest of the list
  356. * to be ignored.
  357. */
  358. if (result.EndPoint != null) {
  359. try {
  360. if (!result.Sock.Blocking) {
  361. int success;
  362. result.Sock.Poll (-1, SelectMode.SelectWrite, out success);
  363. if (success == 0) {
  364. result.Sock.connected = true;
  365. } else {
  366. result.Complete (new SocketException (success));
  367. return;
  368. }
  369. } else {
  370. result.Sock.seed_endpoint = result.EndPoint;
  371. result.Sock.Connect (result.EndPoint);
  372. result.Sock.connected = true;
  373. }
  374. } catch (Exception e) {
  375. result.Complete (e);
  376. return;
  377. }
  378. result.Complete ();
  379. } else if (result.Addresses != null) {
  380. foreach(IPAddress address in result.Addresses) {
  381. IPEndPoint iep = new IPEndPoint (address, result.Port);
  382. SocketAddress serial = iep.Serialize ();
  383. int error = 0;
  384. Socket.Connect_internal (result.Sock.socket, serial, out error);
  385. if (error == 0) {
  386. result.Sock.connected = true;
  387. result.Sock.seed_endpoint = iep;
  388. result.Complete ();
  389. return;
  390. } else if (error != (int)SocketError.InProgress &&
  391. error != (int)SocketError.WouldBlock) {
  392. continue;
  393. }
  394. if (!result.Sock.Blocking) {
  395. int success;
  396. result.Sock.Poll (-1, SelectMode.SelectWrite, out success);
  397. if (success == 0) {
  398. result.Sock.connected = true;
  399. result.Sock.seed_endpoint = iep;
  400. result.Complete ();
  401. return;
  402. }
  403. }
  404. }
  405. result.Complete (new SocketException ((int)SocketError.InProgress));
  406. } else {
  407. result.Complete (new SocketException ((int)SocketError.AddressNotAvailable));
  408. }
  409. }
  410. /* Also only used in 2.0 profile and newer */
  411. public void Disconnect ()
  412. {
  413. #if NET_2_0
  414. try {
  415. result.Sock.Disconnect (result.ReuseSocket);
  416. } catch (Exception e) {
  417. result.Complete (e);
  418. return;
  419. }
  420. result.Complete ();
  421. #else
  422. result.Complete (new SocketException ((int)SocketError.Fault));
  423. #endif
  424. }
  425. public void Receive ()
  426. {
  427. // Actual recv() done in the runtime
  428. result.Complete ();
  429. }
  430. public void ReceiveFrom ()
  431. {
  432. int total = 0;
  433. try {
  434. total = result.Sock.ReceiveFrom_nochecks (result.Buffer,
  435. result.Offset,
  436. result.Size,
  437. result.SockFlags,
  438. ref result.EndPoint);
  439. } catch (Exception e) {
  440. result.Complete (e);
  441. return;
  442. }
  443. result.Complete (total);
  444. }
  445. public void ReceiveGeneric ()
  446. {
  447. #if NET_2_0
  448. int total = 0;
  449. try {
  450. SocketError error;
  451. total = result.Sock.Receive (result.Buffers, result.SockFlags, out error);
  452. } catch (Exception e) {
  453. result.Complete (e);
  454. return;
  455. }
  456. result.Complete (total);
  457. #else
  458. result.Complete (new SocketException ((int)SocketError.Fault));
  459. #endif
  460. }
  461. int send_so_far;
  462. void UpdateSendValues (int last_sent)
  463. {
  464. if (result.error == 0) {
  465. send_so_far += last_sent;
  466. result.Offset += last_sent;
  467. result.Size -= last_sent;
  468. }
  469. }
  470. public void Send ()
  471. {
  472. // Actual send() done in the runtime
  473. if (result.error == 0) {
  474. UpdateSendValues (result.Total);
  475. if (result.Sock.disposed) {
  476. result.Complete ();
  477. return;
  478. }
  479. if (result.Size > 0) {
  480. SocketAsyncCall sac = new SocketAsyncCall (this.Send);
  481. sac.BeginInvoke (null, result);
  482. return; // Have to finish writing everything. See bug #74475.
  483. }
  484. result.Total = send_so_far;
  485. }
  486. result.Complete ();
  487. }
  488. public void SendTo ()
  489. {
  490. int total = 0;
  491. try {
  492. total = result.Sock.SendTo_nochecks (result.Buffer,
  493. result.Offset,
  494. result.Size,
  495. result.SockFlags,
  496. result.EndPoint);
  497. UpdateSendValues (total);
  498. if (result.Size > 0) {
  499. SocketAsyncCall sac = new SocketAsyncCall (this.SendTo);
  500. sac.BeginInvoke (null, result);
  501. return; // Have to finish writing everything. See bug #74475.
  502. }
  503. result.Total = send_so_far;
  504. } catch (Exception e) {
  505. result.Complete (e);
  506. return;
  507. }
  508. result.Complete ();
  509. }
  510. public void SendGeneric ()
  511. {
  512. #if NET_2_0
  513. int total = 0;
  514. try {
  515. SocketError error;
  516. total = result.Sock.Send (result.Buffers, result.SockFlags, out error);
  517. } catch (Exception e) {
  518. result.Complete (e);
  519. return;
  520. }
  521. result.Complete (total);
  522. #else
  523. result.Complete (new SocketException ((int)SocketError.Fault));
  524. #endif
  525. }
  526. }
  527. static Socket () {
  528. // initialize ipv4Supported and ipv6Supported
  529. CheckProtocolSupport ();
  530. }
  531. /* the field "socket" is looked up by name by the runtime */
  532. private IntPtr socket;
  533. private AddressFamily address_family;
  534. private SocketType socket_type;
  535. private ProtocolType protocol_type;
  536. internal bool blocking=true;
  537. private Queue readQ = new Queue (2);
  538. private Queue writeQ = new Queue (2);
  539. delegate void SocketAsyncCall ();
  540. /*
  541. * These two fields are looked up by name by the runtime, don't change
  542. * their name without also updating the runtime code.
  543. */
  544. private static int ipv4Supported = -1, ipv6Supported = -1;
  545. /* When true, the socket was connected at the time of
  546. * the last IO operation
  547. */
  548. private bool connected;
  549. /* true if we called Close_internal */
  550. private bool closed;
  551. internal bool disposed;
  552. /*
  553. * This EndPoint is used when creating new endpoints. Because
  554. * there are many types of EndPoints possible,
  555. * seed_endpoint.Create(addr) is used for creating new ones.
  556. * As such, this value is set on Bind, SentTo, ReceiveFrom,
  557. * Connect, etc.
  558. */
  559. internal EndPoint seed_endpoint = null;
  560. #if NET_2_0
  561. private bool isbound;
  562. private bool islistening;
  563. private bool useoverlappedIO;
  564. #endif
  565. static void AddSockets (ArrayList sockets, IList list, string name)
  566. {
  567. if (list != null) {
  568. foreach (Socket sock in list) {
  569. if (sock == null) // MS throws a NullRef
  570. throw new ArgumentNullException ("name", "Contains a null element");
  571. sockets.Add (sock);
  572. }
  573. }
  574. sockets.Add (null);
  575. }
  576. #if !TARGET_JVM
  577. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  578. private extern static void Select_internal (ref Socket [] sockets,
  579. int microSeconds,
  580. out int error);
  581. #endif
  582. public static void Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
  583. {
  584. ArrayList list = new ArrayList ();
  585. AddSockets (list, checkRead, "checkRead");
  586. AddSockets (list, checkWrite, "checkWrite");
  587. AddSockets (list, checkError, "checkError");
  588. if (list.Count == 3) {
  589. throw new ArgumentNullException ("checkRead, checkWrite, checkError",
  590. "All the lists are null or empty.");
  591. }
  592. int error;
  593. /*
  594. * The 'sockets' array contains: READ socket 0-n, null,
  595. * WRITE socket 0-n, null,
  596. * ERROR socket 0-n, null
  597. */
  598. Socket [] sockets = (Socket []) list.ToArray (typeof (Socket));
  599. Select_internal (ref sockets, microSeconds, out error);
  600. if (error != 0)
  601. throw new SocketException (error);
  602. if (sockets == null) {
  603. if (checkRead != null)
  604. checkRead.Clear ();
  605. if (checkWrite != null)
  606. checkWrite.Clear ();
  607. if (checkError != null)
  608. checkError.Clear ();
  609. return;
  610. }
  611. int mode = 0;
  612. int count = sockets.Length;
  613. IList currentList = checkRead;
  614. int currentIdx = 0;
  615. for (int i = 0; i < count; i++) {
  616. Socket cur_sock;
  617. Socket sock = sockets [i];
  618. if (sock == null) { // separator
  619. if (currentList != null) {
  620. // Remove non-signaled sockets after the current one
  621. int to_remove = currentList.Count - currentIdx;
  622. for (int k = 0; k < to_remove; k++)
  623. currentList.RemoveAt (currentIdx);
  624. }
  625. currentList = (mode == 0) ? checkWrite : checkError;
  626. currentIdx = 0;
  627. mode++;
  628. continue;
  629. }
  630. if (mode == 1 && currentList == checkWrite && !sock.connected) {
  631. if ((int) sock.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0)
  632. sock.connected = true;
  633. }
  634. // Remove non-signaled sockets before the current one
  635. int max = currentList.Count;
  636. while ((cur_sock = (Socket) currentList [currentIdx]) != sock) {
  637. currentList.RemoveAt (currentIdx);
  638. }
  639. currentIdx++;
  640. }
  641. }
  642. // private constructor used by Accept, which already
  643. // has a socket handle to use
  644. private Socket(AddressFamily family, SocketType type,
  645. ProtocolType proto, IntPtr sock)
  646. {
  647. address_family=family;
  648. socket_type=type;
  649. protocol_type=proto;
  650. socket=sock;
  651. connected=true;
  652. }
  653. #if !TARGET_JVM
  654. // Creates a new system socket, returning the handle
  655. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  656. private extern IntPtr Socket_internal(AddressFamily family,
  657. SocketType type,
  658. ProtocolType proto,
  659. out int error);
  660. #endif
  661. private void SocketDefaults ()
  662. {
  663. #if NET_2_0
  664. try {
  665. if (address_family == AddressFamily.InterNetwork /* Need to test IPv6 further ||
  666. address_family == AddressFamily.InterNetworkV6 */) {
  667. /* This is the default, but it
  668. * probably has nasty side
  669. * effects on Linux, as the
  670. * socket option is kludged by
  671. * turning on or off PMTU
  672. * discovery...
  673. */
  674. this.DontFragment = false;
  675. }
  676. //
  677. // Microsoft sets these to 8192, but we are going to keep them
  678. // both to the OS defaults as these have a big performance impact.
  679. // on WebClient performance.
  680. //
  681. //this.ReceiveBufferSize = 8192;
  682. //this.SendBufferSize = 8192;
  683. } catch (SocketException) {
  684. }
  685. #endif
  686. }
  687. public Socket(AddressFamily family, SocketType type, ProtocolType proto)
  688. {
  689. address_family=family;
  690. socket_type=type;
  691. protocol_type=proto;
  692. int error;
  693. socket = Socket_internal (family, type, proto, out error);
  694. if (error != 0)
  695. throw new SocketException (error);
  696. SocketDefaults ();
  697. }
  698. #if NET_2_0
  699. [MonoTODO]
  700. public Socket (SocketInformation socketInformation)
  701. {
  702. throw new NotImplementedException ("SocketInformation not figured out yet");
  703. // ifdef to avoid the warnings.
  704. #if false
  705. //address_family = socketInformation.address_family;
  706. //socket_type = socketInformation.socket_type;
  707. //protocol_type = socketInformation.protocol_type;
  708. address_family = AddressFamily.InterNetwork;
  709. socket_type = SocketType.Stream;
  710. protocol_type = ProtocolType.IP;
  711. int error;
  712. socket = Socket_internal (address_family, socket_type, protocol_type, out error);
  713. if (error != 0)
  714. throw new SocketException (error);
  715. SocketDefaults ();
  716. #endif
  717. }
  718. #endif
  719. public AddressFamily AddressFamily {
  720. get {
  721. return(address_family);
  722. }
  723. }
  724. #if !TARGET_JVM
  725. // Returns the amount of data waiting to be read on socket
  726. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  727. private extern static int Available_internal(IntPtr socket, out int error);
  728. #endif
  729. public int Available {
  730. get {
  731. if (disposed && closed)
  732. throw new ObjectDisposedException (GetType ().ToString ());
  733. int ret, error;
  734. ret = Available_internal(socket, out error);
  735. if (error != 0)
  736. throw new SocketException (error);
  737. return(ret);
  738. }
  739. }
  740. #if !TARGET_JVM
  741. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  742. private extern static void Blocking_internal(IntPtr socket,
  743. bool block,
  744. out int error);
  745. #endif
  746. public bool Blocking {
  747. get {
  748. return(blocking);
  749. }
  750. set {
  751. if (disposed && closed)
  752. throw new ObjectDisposedException (GetType ().ToString ());
  753. int error;
  754. Blocking_internal (socket, value, out error);
  755. if (error != 0)
  756. throw new SocketException (error);
  757. blocking=value;
  758. }
  759. }
  760. public bool Connected {
  761. get {
  762. return(connected);
  763. }
  764. internal set { connected = value; }
  765. }
  766. #if NET_2_0
  767. public bool DontFragment {
  768. get {
  769. if (disposed && closed) {
  770. throw new ObjectDisposedException (GetType ().ToString ());
  771. }
  772. bool dontfragment;
  773. if (address_family == AddressFamily.InterNetwork) {
  774. dontfragment = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment)) != 0;
  775. } else if (address_family == AddressFamily.InterNetworkV6) {
  776. dontfragment = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment)) != 0;
  777. } else {
  778. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  779. }
  780. return(dontfragment);
  781. }
  782. set {
  783. if (disposed && closed) {
  784. throw new ObjectDisposedException (GetType ().ToString ());
  785. }
  786. if (address_family == AddressFamily.InterNetwork) {
  787. SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DontFragment, value?1:0);
  788. } else if (address_family == AddressFamily.InterNetworkV6) {
  789. SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.DontFragment, value?1:0);
  790. } else {
  791. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  792. }
  793. }
  794. }
  795. public bool EnableBroadcast {
  796. get {
  797. if (disposed && closed) {
  798. throw new ObjectDisposedException (GetType ().ToString ());
  799. }
  800. if (protocol_type != ProtocolType.Udp) {
  801. throw new SocketException ((int)SocketError.ProtocolOption);
  802. }
  803. return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast)) != 0);
  804. }
  805. set {
  806. if (disposed && closed) {
  807. throw new ObjectDisposedException (GetType ().ToString ());
  808. }
  809. if (protocol_type != ProtocolType.Udp) {
  810. throw new SocketException ((int)SocketError.ProtocolOption);
  811. }
  812. SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast, value?1:0);
  813. }
  814. }
  815. public bool ExclusiveAddressUse {
  816. get {
  817. if (disposed && closed) {
  818. throw new ObjectDisposedException (GetType ().ToString ());
  819. }
  820. return((int)(GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse)) != 0);
  821. }
  822. set {
  823. if (disposed && closed) {
  824. throw new ObjectDisposedException (GetType ().ToString ());
  825. }
  826. if (isbound) {
  827. throw new InvalidOperationException ("Bind has already been called for this socket");
  828. }
  829. SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, value?1:0);
  830. }
  831. }
  832. public bool IsBound {
  833. get {
  834. return(isbound);
  835. }
  836. }
  837. public LingerOption LingerState {
  838. get {
  839. if (disposed && closed) {
  840. throw new ObjectDisposedException (GetType ().ToString ());
  841. }
  842. return((LingerOption)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Linger));
  843. }
  844. set {
  845. if (disposed && closed) {
  846. throw new ObjectDisposedException (GetType ().ToString ());
  847. }
  848. SetSocketOption (SocketOptionLevel.Socket,
  849. SocketOptionName.Linger,
  850. value);
  851. }
  852. }
  853. public bool MulticastLoopback {
  854. get {
  855. if (disposed && closed) {
  856. throw new ObjectDisposedException (GetType ().ToString ());
  857. }
  858. /* Even though this option can be set
  859. * for TCP sockets on Linux, throw
  860. * this exception anyway to be
  861. * compatible (the MSDN docs say
  862. * "Setting this property on a
  863. * Transmission Control Protocol (TCP)
  864. * socket will have no effect." but
  865. * the MS runtime throws the
  866. * exception...)
  867. */
  868. if (protocol_type == ProtocolType.Tcp) {
  869. throw new SocketException ((int)SocketError.ProtocolOption);
  870. }
  871. bool multicastloopback;
  872. if (address_family == AddressFamily.InterNetwork) {
  873. multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback)) != 0;
  874. } else if (address_family == AddressFamily.InterNetworkV6) {
  875. multicastloopback = (int)(GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback)) != 0;
  876. } else {
  877. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  878. }
  879. return(multicastloopback);
  880. }
  881. set {
  882. if (disposed && closed) {
  883. throw new ObjectDisposedException (GetType ().ToString ());
  884. }
  885. /* Even though this option can be set
  886. * for TCP sockets on Linux, throw
  887. * this exception anyway to be
  888. * compatible (the MSDN docs say
  889. * "Setting this property on a
  890. * Transmission Control Protocol (TCP)
  891. * socket will have no effect." but
  892. * the MS runtime throws the
  893. * exception...)
  894. */
  895. if (protocol_type == ProtocolType.Tcp) {
  896. throw new SocketException ((int)SocketError.ProtocolOption);
  897. }
  898. if (address_family == AddressFamily.InterNetwork) {
  899. SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, value?1:0);
  900. } else if (address_family == AddressFamily.InterNetworkV6) {
  901. SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.MulticastLoopback, value?1:0);
  902. } else {
  903. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  904. }
  905. }
  906. }
  907. public static bool OSSupportsIPv6 {
  908. get {
  909. NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces ();
  910. foreach(NetworkInterface adapter in nics) {
  911. if (adapter.Supports (NetworkInterfaceComponent.IPv6) == true) {
  912. return(true);
  913. } else {
  914. continue;
  915. }
  916. }
  917. return(false);
  918. }
  919. }
  920. public int ReceiveBufferSize {
  921. get {
  922. if (disposed && closed) {
  923. throw new ObjectDisposedException (GetType ().ToString ());
  924. }
  925. return((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer));
  926. }
  927. set {
  928. if (disposed && closed) {
  929. throw new ObjectDisposedException (GetType ().ToString ());
  930. }
  931. if (value < 0) {
  932. throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than zero");
  933. }
  934. SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, value);
  935. }
  936. }
  937. public int SendBufferSize {
  938. get {
  939. if (disposed && closed) {
  940. throw new ObjectDisposedException (GetType ().ToString ());
  941. }
  942. return((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.SendBuffer));
  943. }
  944. set {
  945. if (disposed && closed) {
  946. throw new ObjectDisposedException (GetType ().ToString ());
  947. }
  948. if (value < 0) {
  949. throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than zero");
  950. }
  951. SetSocketOption (SocketOptionLevel.Socket,
  952. SocketOptionName.SendBuffer,
  953. value);
  954. }
  955. }
  956. public short Ttl {
  957. get {
  958. if (disposed && closed) {
  959. throw new ObjectDisposedException (GetType ().ToString ());
  960. }
  961. short ttl_val;
  962. if (address_family == AddressFamily.InterNetwork) {
  963. ttl_val = (short)((int)GetSocketOption (SocketOptionLevel.IP, SocketOptionName.IpTimeToLive));
  964. } else if (address_family == AddressFamily.InterNetworkV6) {
  965. ttl_val = (short)((int)GetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.HopLimit));
  966. } else {
  967. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  968. }
  969. return(ttl_val);
  970. }
  971. set {
  972. if (disposed && closed) {
  973. throw new ObjectDisposedException (GetType ().ToString ());
  974. }
  975. if (address_family == AddressFamily.InterNetwork) {
  976. SetSocketOption (SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, value);
  977. } else if (address_family == AddressFamily.InterNetworkV6) {
  978. SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.HopLimit, value);
  979. } else {
  980. throw new NotSupportedException ("This property is only valid for InterNetwork and InterNetworkV6 sockets");
  981. }
  982. }
  983. }
  984. [MonoTODO ("This doesn't do anything on Mono yet")]
  985. public bool UseOnlyOverlappedIO {
  986. get {
  987. return(useoverlappedIO);
  988. }
  989. set {
  990. useoverlappedIO = value;
  991. }
  992. }
  993. #endif
  994. public IntPtr Handle {
  995. get {
  996. return(socket);
  997. }
  998. }
  999. #if !TARGET_JVM
  1000. // Returns the local endpoint details in addr and port
  1001. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1002. private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, out int error);
  1003. #endif
  1004. // Wish: support non-IP endpoints.
  1005. public EndPoint LocalEndPoint {
  1006. get {
  1007. if (disposed && closed)
  1008. throw new ObjectDisposedException (GetType ().ToString ());
  1009. /*
  1010. * If the seed EndPoint is null, Connect, Bind,
  1011. * etc has not yet been called. MS returns null
  1012. * in this case.
  1013. */
  1014. if (seed_endpoint == null)
  1015. return null;
  1016. SocketAddress sa;
  1017. int error;
  1018. sa=LocalEndPoint_internal(socket, out error);
  1019. if (error != 0)
  1020. throw new SocketException (error);
  1021. return seed_endpoint.Create (sa);
  1022. }
  1023. }
  1024. public ProtocolType ProtocolType {
  1025. get {
  1026. return(protocol_type);
  1027. }
  1028. }
  1029. // Returns the remote endpoint details in addr and port
  1030. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1031. private extern static SocketAddress RemoteEndPoint_internal(IntPtr socket, out int error);
  1032. public EndPoint RemoteEndPoint {
  1033. get {
  1034. if (disposed && closed)
  1035. throw new ObjectDisposedException (GetType ().ToString ());
  1036. /*
  1037. * If the seed EndPoint is null, Connect, Bind,
  1038. * etc has not yet been called. MS returns null
  1039. * in this case.
  1040. */
  1041. if (seed_endpoint == null)
  1042. return null;
  1043. SocketAddress sa;
  1044. int error;
  1045. sa=RemoteEndPoint_internal(socket, out error);
  1046. if (error != 0)
  1047. throw new SocketException (error);
  1048. return seed_endpoint.Create (sa);
  1049. }
  1050. }
  1051. public SocketType SocketType {
  1052. get {
  1053. return(socket_type);
  1054. }
  1055. }
  1056. public static bool SupportsIPv4 {
  1057. get {
  1058. CheckProtocolSupport();
  1059. return ipv4Supported == 1;
  1060. }
  1061. }
  1062. #if NET_2_0
  1063. [ObsoleteAttribute ("Use OSSupportsIPv6 instead")]
  1064. #endif
  1065. public static bool SupportsIPv6 {
  1066. get {
  1067. CheckProtocolSupport();
  1068. return ipv6Supported == 1;
  1069. }
  1070. }
  1071. #if NET_2_0
  1072. public int SendTimeout {
  1073. get {
  1074. if (disposed && closed)
  1075. throw new ObjectDisposedException (GetType ().ToString ());
  1076. return (int)GetSocketOption(
  1077. SocketOptionLevel.Socket,
  1078. SocketOptionName.SendTimeout);
  1079. }
  1080. set {
  1081. if (disposed && closed)
  1082. throw new ObjectDisposedException (GetType ().ToString ());
  1083. if (value < -1)
  1084. throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
  1085. /* According to the MSDN docs we
  1086. * should adjust values between 1 and
  1087. * 499 to 500, but the MS runtime
  1088. * doesn't do this.
  1089. */
  1090. if (value == -1)
  1091. value = 0;
  1092. SetSocketOption(
  1093. SocketOptionLevel.Socket,
  1094. SocketOptionName.SendTimeout, value);
  1095. }
  1096. }
  1097. public int ReceiveTimeout {
  1098. get {
  1099. if (disposed && closed)
  1100. throw new ObjectDisposedException (GetType ().ToString ());
  1101. return (int)GetSocketOption(
  1102. SocketOptionLevel.Socket,
  1103. SocketOptionName.ReceiveTimeout);
  1104. }
  1105. set {
  1106. if (disposed && closed)
  1107. throw new ObjectDisposedException (GetType ().ToString ());
  1108. if (value < -1)
  1109. throw new ArgumentOutOfRangeException ("value", "The value specified for a set operation is less than -1");
  1110. if (value == -1) {
  1111. value = 0;
  1112. }
  1113. SetSocketOption(
  1114. SocketOptionLevel.Socket,
  1115. SocketOptionName.ReceiveTimeout, value);
  1116. }
  1117. }
  1118. public bool NoDelay {
  1119. get {
  1120. if (disposed && closed)
  1121. throw new ObjectDisposedException (GetType ().ToString ());
  1122. if (protocol_type == ProtocolType.Udp)
  1123. throw new SocketException ((int)SocketError.ProtocolOption);
  1124. return (int)(GetSocketOption (
  1125. SocketOptionLevel.Tcp,
  1126. SocketOptionName.NoDelay)) != 0;
  1127. }
  1128. set {
  1129. if (disposed && closed)
  1130. throw new ObjectDisposedException (GetType ().ToString ());
  1131. if (protocol_type == ProtocolType.Udp)
  1132. throw new SocketException ((int)SocketError.ProtocolOption);
  1133. SetSocketOption (
  1134. SocketOptionLevel.Tcp,
  1135. SocketOptionName.NoDelay, value ? 1 : 0);
  1136. }
  1137. }
  1138. #endif
  1139. internal static void CheckProtocolSupport ()
  1140. {
  1141. if(ipv4Supported == -1) {
  1142. try {
  1143. Socket tmp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  1144. tmp.Close();
  1145. ipv4Supported = 1;
  1146. } catch {
  1147. ipv4Supported = 0;
  1148. }
  1149. }
  1150. if (ipv6Supported == -1) {
  1151. #if !NET_2_1
  1152. #if NET_2_0 && CONFIGURATION_DEP
  1153. SettingsSection config;
  1154. config = (SettingsSection) System.Configuration.ConfigurationManager.GetSection ("system.net/settings");
  1155. if (config != null)
  1156. ipv6Supported = config.Ipv6.Enabled ? -1 : 0;
  1157. #else
  1158. NetConfig config = System.Configuration.ConfigurationSettings.GetConfig("system.net/settings") as NetConfig;
  1159. if (config != null)
  1160. ipv6Supported = config.ipv6Enabled ? -1 : 0;
  1161. #endif
  1162. #endif
  1163. if (ipv6Supported != 0) {
  1164. try {
  1165. Socket tmp = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
  1166. tmp.Close();
  1167. ipv6Supported = 1;
  1168. } catch {
  1169. ipv6Supported = 0;
  1170. }
  1171. }
  1172. }
  1173. }
  1174. #if NET_2_0
  1175. public bool AcceptAsync (SocketAsyncEventArgs e)
  1176. {
  1177. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  1178. if (disposed && closed)
  1179. throw new ObjectDisposedException (GetType ().ToString ());
  1180. if (!IsBound)
  1181. throw new InvalidOperationException ("You must call the Bind method before performing this operation.");
  1182. if (!islistening)
  1183. throw new InvalidOperationException ("You must call the Listen method before performing this operation.");
  1184. if (e.BufferList != null)
  1185. throw new ArgumentException ("Multiple buffers cannot be used with this method.");
  1186. if (e.Count < 0)
  1187. throw new ArgumentOutOfRangeException ("e.Count");
  1188. Socket acceptSocket = e.AcceptSocket;
  1189. if (acceptSocket != null) {
  1190. if (acceptSocket.IsBound || acceptSocket.Connected)
  1191. throw new InvalidOperationException ("AcceptSocket: The socket must not be bound or connected.");
  1192. } else
  1193. e.AcceptSocket = new Socket (AddressFamily, SocketType, ProtocolType);
  1194. try {
  1195. e.DoOperation (SocketAsyncOperation.Accept, this);
  1196. } catch {
  1197. ((IDisposable)e).Dispose ();
  1198. throw;
  1199. }
  1200. // We always return true for now
  1201. return true;
  1202. }
  1203. #endif
  1204. // Creates a new system socket, returning the handle
  1205. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1206. private extern static IntPtr Accept_internal(IntPtr sock, out int error, bool blocking);
  1207. Thread blocking_thread;
  1208. public Socket Accept() {
  1209. if (disposed && closed)
  1210. throw new ObjectDisposedException (GetType ().ToString ());
  1211. int error = 0;
  1212. IntPtr sock = (IntPtr) (-1);
  1213. blocking_thread = Thread.CurrentThread;
  1214. try {
  1215. sock = Accept_internal(socket, out error, blocking);
  1216. } catch (ThreadAbortException) {
  1217. if (disposed) {
  1218. #if !NET_2_1
  1219. Thread.ResetAbort ();
  1220. #endif
  1221. error = (int) SocketError.Interrupted;
  1222. }
  1223. } finally {
  1224. blocking_thread = null;
  1225. }
  1226. if (error != 0)
  1227. throw new SocketException (error);
  1228. Socket accepted = new Socket(this.AddressFamily, this.SocketType,
  1229. this.ProtocolType, sock);
  1230. accepted.seed_endpoint = this.seed_endpoint;
  1231. accepted.Blocking = this.Blocking;
  1232. return(accepted);
  1233. }
  1234. internal void Accept (Socket acceptSocket)
  1235. {
  1236. if (disposed && closed)
  1237. throw new ObjectDisposedException (GetType ().ToString ());
  1238. int error = 0;
  1239. IntPtr sock = (IntPtr)(-1);
  1240. blocking_thread = Thread.CurrentThread;
  1241. try {
  1242. sock = Accept_internal (socket, out error, blocking);
  1243. } catch (ThreadAbortException) {
  1244. if (disposed) {
  1245. #if !NET_2_1
  1246. Thread.ResetAbort ();
  1247. #endif
  1248. error = (int)SocketError.Interrupted;
  1249. }
  1250. } finally {
  1251. blocking_thread = null;
  1252. }
  1253. if (error != 0)
  1254. throw new SocketException (error);
  1255. acceptSocket.address_family = this.AddressFamily;
  1256. acceptSocket.socket_type = this.SocketType;
  1257. acceptSocket.protocol_type = this.ProtocolType;
  1258. acceptSocket.socket = sock;
  1259. acceptSocket.connected = true;
  1260. acceptSocket.seed_endpoint = this.seed_endpoint;
  1261. acceptSocket.Blocking = this.Blocking;
  1262. /* FIXME: figure out what if anything else
  1263. * needs to be reset
  1264. */
  1265. }
  1266. public IAsyncResult BeginAccept(AsyncCallback callback,
  1267. object state)
  1268. {
  1269. if (disposed && closed)
  1270. throw new ObjectDisposedException (GetType ().ToString ());
  1271. #if NET_2_0
  1272. /* FIXME: check the 1.1 docs for this too */
  1273. if (!isbound || !islistening)
  1274. throw new InvalidOperationException ();
  1275. #endif
  1276. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Accept);
  1277. Worker worker = new Worker (req);
  1278. SocketAsyncCall sac = new SocketAsyncCall (worker.Accept);
  1279. sac.BeginInvoke (null, req);
  1280. return(req);
  1281. }
  1282. #if NET_2_0
  1283. public IAsyncResult BeginAccept (int receiveSize,
  1284. AsyncCallback callback,
  1285. object state)
  1286. {
  1287. if (disposed && closed)
  1288. throw new ObjectDisposedException (GetType ().ToString ());
  1289. if (receiveSize < 0)
  1290. throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
  1291. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
  1292. Worker worker = new Worker (req);
  1293. SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
  1294. req.Buffer = new byte[receiveSize];
  1295. req.Offset = 0;
  1296. req.Size = receiveSize;
  1297. req.SockFlags = SocketFlags.None;
  1298. sac.BeginInvoke (null, req);
  1299. return(req);
  1300. }
  1301. public IAsyncResult BeginAccept (Socket acceptSocket,
  1302. int receiveSize,
  1303. AsyncCallback callback,
  1304. object state)
  1305. {
  1306. if (disposed && closed)
  1307. throw new ObjectDisposedException (GetType ().ToString ());
  1308. if (receiveSize < 0)
  1309. throw new ArgumentOutOfRangeException ("receiveSize", "receiveSize is less than zero");
  1310. if (acceptSocket != null) {
  1311. if (acceptSocket.disposed && acceptSocket.closed)
  1312. throw new ObjectDisposedException (acceptSocket.GetType ().ToString ());
  1313. if (acceptSocket.IsBound)
  1314. throw new InvalidOperationException ();
  1315. /* For some reason the MS runtime
  1316. * barfs if the new socket is not TCP,
  1317. * even though it's just about to blow
  1318. * away all those parameters
  1319. */
  1320. if (acceptSocket.ProtocolType != ProtocolType.Tcp)
  1321. throw new SocketException ((int)SocketError.InvalidArgument);
  1322. }
  1323. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.AcceptReceive);
  1324. Worker worker = new Worker (req);
  1325. SocketAsyncCall sac = new SocketAsyncCall (worker.AcceptReceive);
  1326. req.Buffer = new byte[receiveSize];
  1327. req.Offset = 0;
  1328. req.Size = receiveSize;
  1329. req.SockFlags = SocketFlags.None;
  1330. req.AcceptSocket = acceptSocket;
  1331. sac.BeginInvoke (null, req);
  1332. return(req);
  1333. }
  1334. #endif
  1335. public IAsyncResult BeginConnect(EndPoint end_point,
  1336. AsyncCallback callback,
  1337. object state) {
  1338. if (disposed && closed)
  1339. throw new ObjectDisposedException (GetType ().ToString ());
  1340. if (end_point == null)
  1341. throw new ArgumentNullException ("end_point");
  1342. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
  1343. req.EndPoint = end_point;
  1344. // Bug #75154: Connect() should not succeed for .Any addresses.
  1345. if (end_point is IPEndPoint) {
  1346. IPEndPoint ep = (IPEndPoint) end_point;
  1347. if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any)) {
  1348. req.Complete (new SocketException ((int) SocketError.AddressNotAvailable), true);
  1349. return req;
  1350. }
  1351. }
  1352. int error = 0;
  1353. if (!blocking) {
  1354. SocketAddress serial = end_point.Serialize ();
  1355. Connect_internal (socket, serial, out error);
  1356. if (error == 0) {
  1357. // succeeded synch
  1358. connected = true;
  1359. req.Complete (true);
  1360. } else if (error != (int) SocketError.InProgress && error != (int) SocketError.WouldBlock) {
  1361. // error synch
  1362. connected = false;
  1363. req.Complete (new SocketException (error), true);
  1364. }
  1365. }
  1366. if (blocking || error == (int) SocketError.InProgress || error == (int) SocketError.WouldBlock) {
  1367. // continue asynch
  1368. connected = false;
  1369. Worker worker = new Worker (req);
  1370. SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
  1371. sac.BeginInvoke (null, req);
  1372. }
  1373. return(req);
  1374. }
  1375. #if NET_2_0
  1376. public IAsyncResult BeginConnect (IPAddress address, int port,
  1377. AsyncCallback callback,
  1378. object state)
  1379. {
  1380. if (disposed && closed)
  1381. throw new ObjectDisposedException (GetType ().ToString ());
  1382. if (address == null)
  1383. throw new ArgumentNullException ("address");
  1384. if (address.ToString ().Length == 0)
  1385. throw new ArgumentException ("The length of the IP address is zero");
  1386. if (islistening)
  1387. throw new InvalidOperationException ();
  1388. IPEndPoint iep = new IPEndPoint (address, port);
  1389. return(BeginConnect (iep, callback, state));
  1390. }
  1391. public IAsyncResult BeginConnect (IPAddress[] addresses,
  1392. int port,
  1393. AsyncCallback callback,
  1394. object state)
  1395. {
  1396. if (disposed && closed)
  1397. throw new ObjectDisposedException (GetType ().ToString ());
  1398. if (addresses == null)
  1399. throw new ArgumentNullException ("addresses");
  1400. if (this.AddressFamily != AddressFamily.InterNetwork &&
  1401. this.AddressFamily != AddressFamily.InterNetworkV6)
  1402. throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
  1403. if (islistening)
  1404. throw new InvalidOperationException ();
  1405. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
  1406. req.Addresses = addresses;
  1407. req.Port = port;
  1408. connected = false;
  1409. Worker worker = new Worker (req);
  1410. SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
  1411. sac.BeginInvoke (null, req);
  1412. return(req);
  1413. }
  1414. public IAsyncResult BeginConnect (string host, int port,
  1415. AsyncCallback callback,
  1416. object state)
  1417. {
  1418. if (disposed && closed)
  1419. throw new ObjectDisposedException (GetType ().ToString ());
  1420. if (host == null)
  1421. throw new ArgumentNullException ("host");
  1422. if (address_family != AddressFamily.InterNetwork &&
  1423. address_family != AddressFamily.InterNetworkV6)
  1424. throw new NotSupportedException ("This method is valid only for sockets in the InterNetwork and InterNetworkV6 families");
  1425. if (islistening)
  1426. throw new InvalidOperationException ();
  1427. IPHostEntry hostent = Dns.GetHostEntry (host);
  1428. return (BeginConnect (hostent.AddressList, port, callback, state));
  1429. }
  1430. public IAsyncResult BeginDisconnect (bool reuseSocket,
  1431. AsyncCallback callback,
  1432. object state)
  1433. {
  1434. if (disposed && closed)
  1435. throw new ObjectDisposedException (GetType ().ToString ());
  1436. SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Disconnect);
  1437. req.ReuseSocket = reuseSocket;
  1438. Worker worker = new Worker (req);
  1439. SocketAsyncCall sac = new SocketAsyncCall (worker.Disconnect);
  1440. sac.BeginInvoke (null, req);
  1441. return(req);
  1442. }
  1443. #endif
  1444. public IAsyncResult BeginReceive(byte[] buffer, int offset,
  1445. int size,
  1446. SocketFlags socket_flags,
  1447. AsyncCallback callback,
  1448. object state) {
  1449. if (disposed && closed)
  1450. throw new ObjectDisposedException (GetType ().ToString ());
  1451. if (buffer == null)
  1452. throw new ArgumentNullException ("buffer");
  1453. if (offset < 0 || offset > buffer.Length)
  1454. throw new ArgumentOutOfRangeException ("offset");
  1455. if (size < 0 || offset + size > buffer.Length)
  1456. throw new ArgumentOutOfRangeException ("size");
  1457. SocketAsyncResult req;
  1458. lock (readQ) {
  1459. req = new SocketAsyncResult (this, state, callback, SocketOperation.Receive);
  1460. req.Buffer = buffer;
  1461. req.Offset = offset;
  1462. req.Size = size;
  1463. req.SockFlags = socket_flags;
  1464. readQ.Enqueue (req);
  1465. if (readQ.Count == 1) {
  1466. Worker worker = new Worker (req);
  1467. SocketAsyncCall sac = new SocketAsyncCall (worker.Receive);
  1468. sac.BeginInvoke (null, req);
  1469. }
  1470. }
  1471. return req;
  1472. }
  1473. #if NET_2_0
  1474. public IAsyncResult BeginReceive (byte[] buffer, int offset,
  1475. int size, SocketFlags flags,
  1476. out SocketError error,
  1477. AsyncCallback callback,
  1478. object state)
  1479. {
  1480. /* As far as I can tell from the docs and from
  1481. * experimentation, a pointer to the
  1482. * SocketError parameter is not supposed to be
  1483. * saved for the async parts. And as we don't
  1484. * set any socket errors in the setup code, we
  1485. * just have to set it to Success.
  1486. */
  1487. error = SocketError.Success;
  1488. return (BeginReceive (buffer, offset, size, flags, callback, state));
  1489. }
  1490. [CLSCompliant (false)]
  1491. public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
  1492. SocketFlags socketFlags,
  1493. AsyncCallback callback,
  1494. object state)
  1495. {
  1496. if (disposed && closed)
  1497. throw new ObjectDisposedException (GetType ().ToString ());
  1498. if (buffers == null)
  1499. throw new ArgumentNullException ("buffers");
  1500. SocketAsyncResult req;
  1501. lock(readQ) {
  1502. req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveGeneric);
  1503. req.Buffers = buffers;
  1504. req.SockFlags = socketFlags;
  1505. readQ.Enqueue (req);
  1506. if (readQ.Count == 1) {
  1507. Worker worker = new Worker (req);
  1508. SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveGeneric);
  1509. sac.BeginInvoke (null, req);
  1510. }
  1511. }
  1512. return(req);
  1513. }
  1514. [CLSCompliant (false)]
  1515. public IAsyncResult BeginReceive (IList<ArraySegment<byte>> buffers,
  1516. SocketFlags socketFlags,
  1517. out SocketError errorCode,
  1518. AsyncCallback callback,
  1519. object state)
  1520. {
  1521. /* I assume the same SocketError semantics as
  1522. * above
  1523. */
  1524. errorCode = SocketError.Success;
  1525. return (BeginReceive (buffers, socketFlags, callback, state));
  1526. }
  1527. #endif
  1528. public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset,
  1529. int size,
  1530. SocketFlags socket_flags,
  1531. ref EndPoint remote_end,
  1532. AsyncCallback callback,
  1533. object state) {
  1534. if (disposed && closed)
  1535. throw new ObjectDisposedException (GetType ().ToString ());
  1536. if (buffer == null)
  1537. throw new ArgumentNullException ("buffer");
  1538. if (offset < 0)
  1539. throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
  1540. if (size < 0)
  1541. throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
  1542. if (offset + size > buffer.Length)
  1543. throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
  1544. SocketAsyncResult req;
  1545. lock (readQ) {
  1546. req = new SocketAsyncResult (this, state, callback, SocketOperation.ReceiveFrom);
  1547. req.Buffer = buffer;
  1548. req.Offset = offset;
  1549. req.Size = size;
  1550. req.SockFlags = socket_flags;
  1551. req.EndPoint = remote_end;
  1552. readQ.Enqueue (req);
  1553. if (readQ.Count == 1) {
  1554. Worker worker = new Worker (req);
  1555. SocketAsyncCall sac = new SocketAsyncCall (worker.ReceiveFrom);
  1556. sac.BeginInvoke (null, req);
  1557. }
  1558. }
  1559. return req;
  1560. }
  1561. #if NET_2_0
  1562. [MonoTODO]
  1563. public IAsyncResult BeginReceiveMessageFrom (
  1564. byte[] buffer, int offset, int size,
  1565. SocketFlags socketFlags, ref EndPoint remoteEP,
  1566. AsyncCallback callback, object state)
  1567. {
  1568. if (disposed && closed)
  1569. throw new ObjectDisposedException (GetType ().ToString ());
  1570. if (buffer == null)
  1571. throw new ArgumentNullException ("buffer");
  1572. if (remoteEP == null)
  1573. throw new ArgumentNullException ("remoteEP");
  1574. if (offset < 0 || offset > buffer.Length)
  1575. throw new ArgumentOutOfRangeException ("offset");
  1576. if (size < 0 || offset + size > buffer.Length)
  1577. throw new ArgumentOutOfRangeException ("size");
  1578. throw new NotImplementedException ();
  1579. }
  1580. #endif
  1581. public IAsyncResult BeginSend (byte[] buffer, int offset, int size, SocketFlags socket_flags,
  1582. AsyncCallback callback, object state)
  1583. {
  1584. if (disposed && closed)
  1585. throw new ObjectDisposedException (GetType ().ToString ());
  1586. if (buffer == null)
  1587. throw new ArgumentNullException ("buffer");
  1588. if (offset < 0)
  1589. throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
  1590. if (size < 0)
  1591. throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
  1592. if (offset + size > buffer.Length)
  1593. throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
  1594. #if NET_2_0
  1595. /* TODO: Check this exception in the 1.1 profile */
  1596. if (!connected)
  1597. throw new SocketException ((int)SocketError.NotConnected);
  1598. #endif
  1599. SocketAsyncResult req;
  1600. lock (writeQ) {
  1601. req = new SocketAsyncResult (this, state, callback, SocketOperation.Send);
  1602. req.Buffer = buffer;
  1603. req.Offset = offset;
  1604. req.Size = size;
  1605. req.SockFlags = socket_flags;
  1606. writeQ.Enqueue (req);
  1607. if (writeQ.Count == 1) {
  1608. Worker worker = new Worker (req);
  1609. SocketAsyncCall sac = new SocketAsyncCall (worker.Send);
  1610. sac.BeginInvoke (null, req);
  1611. }
  1612. }
  1613. return req;
  1614. }
  1615. #if NET_2_0
  1616. public IAsyncResult BeginSend (byte[] buffer, int offset,
  1617. int size,
  1618. SocketFlags socketFlags,
  1619. out SocketError errorCode,
  1620. AsyncCallback callback,
  1621. object state)
  1622. {
  1623. if (!connected) {
  1624. errorCode = SocketError.NotConnected;
  1625. throw new SocketException ((int)errorCode);
  1626. }
  1627. errorCode = SocketError.Success;
  1628. return (BeginSend (buffer, offset, size, socketFlags, callback,
  1629. state));
  1630. }
  1631. public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
  1632. SocketFlags socketFlags,
  1633. AsyncCallback callback,
  1634. object state)
  1635. {
  1636. if (disposed && closed)
  1637. throw new ObjectDisposedException (GetType ().ToString ());
  1638. if (buffers == null)
  1639. throw new ArgumentNullException ("buffers");
  1640. if (!connected)
  1641. throw new SocketException ((int)SocketError.NotConnected);
  1642. SocketAsyncResult req;
  1643. lock (writeQ) {
  1644. req = new SocketAsyncResult (this, state, callback, SocketOperation.SendGeneric);
  1645. req.Buffers = buffers;
  1646. req.SockFlags = socketFlags;
  1647. writeQ.Enqueue (req);
  1648. if (writeQ.Count == 1) {
  1649. Worker worker = new Worker (req);
  1650. SocketAsyncCall sac = new SocketAsyncCall (worker.SendGeneric);
  1651. sac.BeginInvoke (null, req);
  1652. }
  1653. }
  1654. return(req);
  1655. }
  1656. [CLSCompliant (false)]
  1657. public IAsyncResult BeginSend (IList<ArraySegment<byte>> buffers,
  1658. SocketFlags socketFlags,
  1659. out SocketError errorCode,
  1660. AsyncCallback callback,
  1661. object state)
  1662. {
  1663. if (!connected) {
  1664. errorCode = SocketError.NotConnected;
  1665. throw new SocketException ((int)errorCode);
  1666. }
  1667. errorCode = SocketError.Success;
  1668. return (BeginSend (buffers, socketFlags, callback, state));
  1669. }
  1670. [MonoTODO ("Not implemented")]
  1671. public IAsyncResult BeginSendFile (string fileName,
  1672. AsyncCallback callback,
  1673. object state)
  1674. {
  1675. if (disposed && closed)
  1676. throw new ObjectDisposedException (GetType ().ToString ());
  1677. if (!connected)
  1678. throw new NotSupportedException ();
  1679. if (!File.Exists (fileName))
  1680. throw new FileNotFoundException ();
  1681. throw new NotImplementedException ();
  1682. }
  1683. [MonoTODO ("Not implemented")]
  1684. public IAsyncResult BeginSendFile (string fileName,
  1685. byte[] preBuffer,
  1686. byte[] postBuffer,
  1687. TransmitFileOptions flags,
  1688. AsyncCallback callback,
  1689. object state)
  1690. {
  1691. if (disposed && closed)
  1692. throw new ObjectDisposedException (GetType ().ToString ());
  1693. if (!connected)
  1694. throw new NotSupportedException ();
  1695. if (!File.Exists (fileName))
  1696. throw new FileNotFoundException ();
  1697. throw new NotImplementedException ();
  1698. }
  1699. #endif
  1700. public IAsyncResult BeginSendTo(byte[] buffer, int offset,
  1701. int size,
  1702. SocketFlags socket_flags,
  1703. EndPoint remote_end,
  1704. AsyncCallback callback,
  1705. object state) {
  1706. if (disposed && closed)
  1707. throw new ObjectDisposedException (GetType ().ToString ());
  1708. if (buffer == null)
  1709. throw new ArgumentNullException ("buffer");
  1710. if (offset < 0)
  1711. throw new ArgumentOutOfRangeException ("offset", "offset must be >= 0");
  1712. if (size < 0)
  1713. throw new ArgumentOutOfRangeException ("size", "size must be >= 0");
  1714. if (offset + size > buffer.Length)
  1715. throw new ArgumentOutOfRangeException ("offset, size", "offset + size exceeds the buffer length");
  1716. SocketAsyncResult req;
  1717. lock (writeQ) {
  1718. req = new SocketAsyncResult (this, state, callback, SocketOperation.SendTo);
  1719. req.Buffer = buffer;
  1720. req.Offset = offset;
  1721. req.Size = size;
  1722. req.SockFlags = socket_flags;
  1723. req.EndPoint = remote_end;
  1724. writeQ.Enqueue (req);
  1725. if (writeQ.Count == 1) {
  1726. Worker worker = new Worker (req);
  1727. SocketAsyncCall sac = new SocketAsyncCall (worker.SendTo);
  1728. sac.BeginInvoke (null, req);
  1729. }
  1730. }
  1731. return req;
  1732. }
  1733. // Creates a new system socket, returning the handle
  1734. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1735. private extern static void Bind_internal(IntPtr sock,
  1736. SocketAddress sa,
  1737. out int error);
  1738. public void Bind(EndPoint local_end) {
  1739. if (disposed && closed)
  1740. throw new ObjectDisposedException (GetType ().ToString ());
  1741. if (local_end == null)
  1742. throw new ArgumentNullException("local_end");
  1743. int error;
  1744. Bind_internal(socket, local_end.Serialize(), out error);
  1745. if (error != 0)
  1746. throw new SocketException (error);
  1747. #if NET_2_0
  1748. if (error == 0)
  1749. isbound = true;
  1750. #endif
  1751. seed_endpoint = local_end;
  1752. }
  1753. // Closes the socket
  1754. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1755. private extern static void Close_internal(IntPtr socket, out int error);
  1756. public void Close()
  1757. {
  1758. ((IDisposable) this).Dispose ();
  1759. }
  1760. #if NET_2_0 && !NET_2_1
  1761. public void Close (int timeout)
  1762. {
  1763. System.Timers.Timer close_timer = new System.Timers.Timer ();
  1764. close_timer.Elapsed += new ElapsedEventHandler (OnTimeoutClose);
  1765. close_timer.Interval = timeout * 1000;
  1766. close_timer.AutoReset = false;
  1767. close_timer.Enabled = true;
  1768. }
  1769. private void OnTimeoutClose (object source, ElapsedEventArgs e)
  1770. {
  1771. this.Close ();
  1772. }
  1773. public bool ConnectAsync (SocketAsyncEventArgs e)
  1774. {
  1775. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  1776. if (disposed && closed)
  1777. throw new ObjectDisposedException (GetType ().ToString ());
  1778. if (islistening)
  1779. throw new InvalidOperationException ("You may not perform this operation after calling the Listen method.");
  1780. if (e.RemoteEndPoint == null)
  1781. throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
  1782. if (e.BufferList != null)
  1783. throw new ArgumentException ("Multiple buffers cannot be used with this method.");
  1784. e.DoOperation (SocketAsyncOperation.Connect, this);
  1785. // We always return true for now
  1786. return true;
  1787. }
  1788. #endif
  1789. // Connects to the remote address
  1790. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1791. private extern static void Connect_internal(IntPtr sock,
  1792. SocketAddress sa,
  1793. out int error);
  1794. public void Connect(EndPoint remote_end) {
  1795. if (disposed && closed)
  1796. throw new ObjectDisposedException (GetType ().ToString ());
  1797. if (remote_end == null)
  1798. throw new ArgumentNullException("remote_end");
  1799. if (remote_end is IPEndPoint) {
  1800. IPEndPoint ep = (IPEndPoint) remote_end;
  1801. if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any))
  1802. throw new SocketException ((int) SocketError.AddressNotAvailable);
  1803. }
  1804. #if NET_2_1
  1805. // Check for SL2.0b1 restrictions
  1806. // - tcp only
  1807. // - SiteOfOrigin
  1808. // - port 4502->4532 + default
  1809. if (protocol_type != ProtocolType.Tcp)
  1810. throw new SocketException ((int) SocketError.AccessDenied);
  1811. //FIXME: replace 80 by Application.Curent.Host.Source.Port
  1812. if (remote_end is IPEndPoint)
  1813. if (((remote_end as IPEndPoint).Port < 4502 || (remote_end as IPEndPoint).Port > 4530) && (remote_end as IPEndPoint).Port != 80)
  1814. throw new SocketException ((int) SocketError.AccessDenied);
  1815. else //unsuported endpoint type
  1816. throw new SocketException ((int) SocketError.AccessDenied);
  1817. //FIXME: check for Application.Curent.Host.Source.DnsSafeHost
  1818. #endif
  1819. #if NET_2_0
  1820. /* TODO: check this for the 1.1 profile too */
  1821. if (islistening)
  1822. throw new InvalidOperationException ();
  1823. #endif
  1824. SocketAddress serial = remote_end.Serialize ();
  1825. int error = 0;
  1826. blocking_thread = Thread.CurrentThread;
  1827. try {
  1828. Connect_internal (socket, serial, out error);
  1829. } catch (ThreadAbortException) {
  1830. if (disposed) {
  1831. #if !NET_2_1 //2.1 profile does not contains Thread.ResetAbort
  1832. Thread.ResetAbort ();
  1833. #endif
  1834. error = (int) SocketError.Interrupted;
  1835. }
  1836. } finally {
  1837. blocking_thread = null;
  1838. }
  1839. if (error != 0)
  1840. throw new SocketException (error);
  1841. connected=true;
  1842. #if NET_2_0
  1843. isbound = true;
  1844. #endif
  1845. seed_endpoint = remote_end;
  1846. }
  1847. #if NET_2_0
  1848. public void Connect (IPAddress address, int port)
  1849. {
  1850. Connect (new IPEndPoint (address, port));
  1851. }
  1852. public void Connect (IPAddress[] addresses, int port)
  1853. {
  1854. if (disposed && closed)
  1855. throw new ObjectDisposedException (GetType ().ToString ());
  1856. if (addresses == null)
  1857. throw new ArgumentNullException ("addresses");
  1858. if (this.AddressFamily != AddressFamily.InterNetwork &&
  1859. this.AddressFamily != AddressFamily.InterNetworkV6)
  1860. throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
  1861. if (islistening)
  1862. throw new InvalidOperationException ();
  1863. /* FIXME: do non-blocking sockets Poll here? */
  1864. foreach (IPAddress address in addresses) {
  1865. IPEndPoint iep = new IPEndPoint (address,
  1866. port);
  1867. SocketAddress serial = iep.Serialize ();
  1868. int error = 0;
  1869. Connect_internal (socket, serial, out error);
  1870. if (error == 0) {
  1871. connected = true;
  1872. seed_endpoint = iep;
  1873. return;
  1874. } else if (error != (int)SocketError.InProgress &&
  1875. error != (int)SocketError.WouldBlock) {
  1876. continue;
  1877. }
  1878. if (!blocking) {
  1879. Poll (-1, SelectMode.SelectWrite);
  1880. int success = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
  1881. if (success == 0) {
  1882. connected = true;
  1883. seed_endpoint = iep;
  1884. return;
  1885. }
  1886. }
  1887. }
  1888. }
  1889. public void Connect (string host, int port)
  1890. {
  1891. IPHostEntry hostent = Dns.GetHostEntry (host);
  1892. Connect (hostent.AddressList, port);
  1893. }
  1894. #if NET_2_0
  1895. public bool DisconnectAsync (SocketAsyncEventArgs e)
  1896. {
  1897. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  1898. if (disposed && closed)
  1899. throw new ObjectDisposedException (GetType ().ToString ());
  1900. e.DoOperation (SocketAsyncOperation.Disconnect, this);
  1901. return true;
  1902. }
  1903. #endif
  1904. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1905. private extern static void Disconnect_internal(IntPtr sock,
  1906. bool reuse,
  1907. out int error);
  1908. /* According to the docs, the MS runtime will throw
  1909. * PlatformNotSupportedException if the platform is
  1910. * newer than w2k. We should be able to cope...
  1911. */
  1912. public void Disconnect (bool reuseSocket)
  1913. {
  1914. if (disposed && closed)
  1915. throw new ObjectDisposedException (GetType ().ToString ());
  1916. int error = 0;
  1917. Disconnect_internal (socket, reuseSocket, out error);
  1918. if (error != 0) {
  1919. if (error == 50) {
  1920. /* ERROR_NOT_SUPPORTED */
  1921. throw new PlatformNotSupportedException ();
  1922. } else {
  1923. throw new SocketException (error);
  1924. }
  1925. }
  1926. connected = false;
  1927. if (reuseSocket) {
  1928. /* Do managed housekeeping here... */
  1929. }
  1930. }
  1931. [MonoTODO ("Not implemented")]
  1932. public SocketInformation DuplicateAndClose (int targetProcessId)
  1933. {
  1934. /* Need to serialize this socket into a
  1935. * SocketInformation struct, but must study
  1936. * the MS implementation harder to figure out
  1937. * behaviour as documentation is lacking
  1938. */
  1939. throw new NotImplementedException ();
  1940. }
  1941. #endif
  1942. public Socket EndAccept (IAsyncResult result)
  1943. {
  1944. int bytes;
  1945. byte[] buffer;
  1946. return(EndAccept (out buffer, out bytes, result));
  1947. }
  1948. #if NET_2_0
  1949. public Socket EndAccept (out byte[] buffer,
  1950. IAsyncResult asyncResult)
  1951. {
  1952. int bytes;
  1953. return(EndAccept (out buffer, out bytes, asyncResult));
  1954. }
  1955. #endif
  1956. #if NET_2_0
  1957. public
  1958. #else
  1959. private
  1960. #endif
  1961. Socket EndAccept (out byte[] buffer, out int bytesTransferred,
  1962. IAsyncResult asyncResult)
  1963. {
  1964. if (disposed && closed)
  1965. throw new ObjectDisposedException (GetType ().ToString ());
  1966. if (asyncResult == null)
  1967. throw new ArgumentNullException ("asyncResult");
  1968. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  1969. if (req == null)
  1970. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  1971. if (!asyncResult.IsCompleted)
  1972. asyncResult.AsyncWaitHandle.WaitOne ();
  1973. req.CheckIfThrowDelayedException ();
  1974. buffer = req.Buffer;
  1975. bytesTransferred = req.Total;
  1976. return(req.Socket);
  1977. }
  1978. public void EndConnect (IAsyncResult result)
  1979. {
  1980. if (disposed && closed)
  1981. throw new ObjectDisposedException (GetType ().ToString ());
  1982. if (result == null)
  1983. throw new ArgumentNullException ("result");
  1984. SocketAsyncResult req = result as SocketAsyncResult;
  1985. if (req == null)
  1986. throw new ArgumentException ("Invalid IAsyncResult", "result");
  1987. if (!result.IsCompleted)
  1988. result.AsyncWaitHandle.WaitOne();
  1989. req.CheckIfThrowDelayedException();
  1990. }
  1991. #if NET_2_0
  1992. public void EndDisconnect (IAsyncResult asyncResult)
  1993. {
  1994. if (disposed && closed)
  1995. throw new ObjectDisposedException (GetType ().ToString ());
  1996. if (asyncResult == null)
  1997. throw new ArgumentNullException ("asyncResult");
  1998. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  1999. if (req == null)
  2000. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  2001. if (!asyncResult.IsCompleted)
  2002. asyncResult.AsyncWaitHandle.WaitOne ();
  2003. req.CheckIfThrowDelayedException ();
  2004. }
  2005. #endif
  2006. public int EndReceive (IAsyncResult result)
  2007. {
  2008. SocketError error;
  2009. return (EndReceive (result, out error));
  2010. }
  2011. #if NET_2_0
  2012. public
  2013. #else
  2014. private
  2015. #endif
  2016. int EndReceive (IAsyncResult asyncResult, out SocketError errorCode)
  2017. {
  2018. if (disposed && closed)
  2019. throw new ObjectDisposedException (GetType ().ToString ());
  2020. if (asyncResult == null)
  2021. throw new ArgumentNullException ("asyncResult");
  2022. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  2023. if (req == null)
  2024. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  2025. if (!asyncResult.IsCompleted)
  2026. asyncResult.AsyncWaitHandle.WaitOne ();
  2027. errorCode = req.ErrorCode;
  2028. req.CheckIfThrowDelayedException ();
  2029. return(req.Total);
  2030. }
  2031. public int EndReceiveFrom(IAsyncResult result, ref EndPoint end_point)
  2032. {
  2033. if (disposed && closed)
  2034. throw new ObjectDisposedException (GetType ().ToString ());
  2035. if (result == null)
  2036. throw new ArgumentNullException ("result");
  2037. SocketAsyncResult req = result as SocketAsyncResult;
  2038. if (req == null)
  2039. throw new ArgumentException ("Invalid IAsyncResult", "result");
  2040. if (!result.IsCompleted)
  2041. result.AsyncWaitHandle.WaitOne();
  2042. req.CheckIfThrowDelayedException();
  2043. end_point = req.EndPoint;
  2044. return req.Total;
  2045. }
  2046. #if NET_2_0
  2047. [MonoTODO]
  2048. public int EndReceiveMessageFrom (IAsyncResult asyncResult,
  2049. ref SocketFlags socketFlags,
  2050. ref EndPoint endPoint,
  2051. out IPPacketInformation ipPacketInformation)
  2052. {
  2053. if (disposed && closed)
  2054. throw new ObjectDisposedException (GetType ().ToString ());
  2055. if (asyncResult == null)
  2056. throw new ArgumentNullException ("asyncResult");
  2057. if (endPoint == null)
  2058. throw new ArgumentNullException ("endPoint");
  2059. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  2060. if (req == null)
  2061. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  2062. throw new NotImplementedException ();
  2063. }
  2064. #endif
  2065. public int EndSend (IAsyncResult result)
  2066. {
  2067. SocketError error;
  2068. return(EndSend (result, out error));
  2069. }
  2070. #if NET_2_0
  2071. public
  2072. #else
  2073. private
  2074. #endif
  2075. int EndSend (IAsyncResult asyncResult, out SocketError errorCode)
  2076. {
  2077. if (disposed && closed)
  2078. throw new ObjectDisposedException (GetType ().ToString ());
  2079. if (asyncResult == null)
  2080. throw new ArgumentNullException ("asyncResult");
  2081. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  2082. if (req == null)
  2083. throw new ArgumentException ("Invalid IAsyncResult", "result");
  2084. if (!asyncResult.IsCompleted)
  2085. asyncResult.AsyncWaitHandle.WaitOne ();
  2086. errorCode = req.ErrorCode;
  2087. req.CheckIfThrowDelayedException ();
  2088. return(req.Total);
  2089. }
  2090. #if NET_2_0
  2091. [MonoTODO]
  2092. public void EndSendFile (IAsyncResult asyncResult)
  2093. {
  2094. if (disposed && closed)
  2095. throw new ObjectDisposedException (GetType ().ToString ());
  2096. if (asyncResult == null)
  2097. throw new ArgumentNullException ("asyncResult");
  2098. SocketAsyncResult req = asyncResult as SocketAsyncResult;
  2099. if (req == null)
  2100. throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
  2101. throw new NotImplementedException ();
  2102. }
  2103. #endif
  2104. public int EndSendTo (IAsyncResult result)
  2105. {
  2106. if (disposed && closed)
  2107. throw new ObjectDisposedException (GetType ().ToString ());
  2108. if (result == null)
  2109. throw new ArgumentNullException ("result");
  2110. SocketAsyncResult req = result as SocketAsyncResult;
  2111. if (req == null)
  2112. throw new ArgumentException ("Invalid IAsyncResult", "result");
  2113. if (!result.IsCompleted)
  2114. result.AsyncWaitHandle.WaitOne();
  2115. req.CheckIfThrowDelayedException();
  2116. return req.Total;
  2117. }
  2118. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2119. private extern static void GetSocketOption_obj_internal(IntPtr socket,
  2120. SocketOptionLevel level, SocketOptionName name, out object obj_val,
  2121. out int error);
  2122. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2123. private extern static void GetSocketOption_arr_internal(IntPtr socket,
  2124. SocketOptionLevel level, SocketOptionName name, ref byte[] byte_val,
  2125. out int error);
  2126. public object GetSocketOption (SocketOptionLevel level, SocketOptionName name)
  2127. {
  2128. if (disposed && closed)
  2129. throw new ObjectDisposedException (GetType ().ToString ());
  2130. object obj_val;
  2131. int error;
  2132. GetSocketOption_obj_internal(socket, level, name, out obj_val,
  2133. out error);
  2134. if (error != 0)
  2135. throw new SocketException (error);
  2136. if (name == SocketOptionName.Linger) {
  2137. return((LingerOption)obj_val);
  2138. } else if (name==SocketOptionName.AddMembership ||
  2139. name==SocketOptionName.DropMembership) {
  2140. return((MulticastOption)obj_val);
  2141. } else if (obj_val is int) {
  2142. return((int)obj_val);
  2143. } else {
  2144. return(obj_val);
  2145. }
  2146. }
  2147. public void GetSocketOption (SocketOptionLevel level, SocketOptionName name, byte [] opt_value)
  2148. {
  2149. if (disposed && closed)
  2150. throw new ObjectDisposedException (GetType ().ToString ());
  2151. int error;
  2152. GetSocketOption_arr_internal(socket, level, name, ref opt_value,
  2153. out error);
  2154. if (error != 0)
  2155. throw new SocketException (error);
  2156. }
  2157. public byte [] GetSocketOption (SocketOptionLevel level, SocketOptionName name, int length)
  2158. {
  2159. if (disposed && closed)
  2160. throw new ObjectDisposedException (GetType ().ToString ());
  2161. byte[] byte_val=new byte[length];
  2162. int error;
  2163. GetSocketOption_arr_internal(socket, level, name, ref byte_val,
  2164. out error);
  2165. if (error != 0)
  2166. throw new SocketException (error);
  2167. return(byte_val);
  2168. }
  2169. // See Socket.IOControl, WSAIoctl documentation in MSDN. The
  2170. // common options between UNIX and Winsock are FIONREAD,
  2171. // FIONBIO and SIOCATMARK. Anything else will depend on the
  2172. // system.
  2173. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2174. extern static int WSAIoctl (IntPtr sock, int ioctl_code, byte [] input,
  2175. byte [] output, out int error);
  2176. public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
  2177. {
  2178. if (disposed)
  2179. throw new ObjectDisposedException (GetType ().ToString ());
  2180. int error;
  2181. int result = WSAIoctl (socket, ioctl_code, in_value, out_value,
  2182. out error);
  2183. if (error != 0)
  2184. throw new SocketException (error);
  2185. if (result == -1)
  2186. throw new InvalidOperationException ("Must use Blocking property instead.");
  2187. return result;
  2188. }
  2189. #if NET_2_0
  2190. [MonoTODO]
  2191. public int IOControl (IOControlCode ioControlCode,
  2192. byte[] optionInValue,
  2193. byte[] optionOutValue)
  2194. {
  2195. /* Probably just needs to mirror the int
  2196. * overload, but more investigation needed.
  2197. */
  2198. throw new NotImplementedException ();
  2199. }
  2200. #endif
  2201. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2202. private extern static void Listen_internal(IntPtr sock, int backlog,
  2203. out int error);
  2204. public void Listen (int backlog)
  2205. {
  2206. if (disposed && closed)
  2207. throw new ObjectDisposedException (GetType ().ToString ());
  2208. #if NET_2_0
  2209. /* TODO: check if this should be thrown in the
  2210. * 1.1 profile too
  2211. */
  2212. if (!isbound)
  2213. throw new SocketException ((int)SocketError.InvalidArgument);
  2214. #endif
  2215. int error;
  2216. Listen_internal(socket, backlog, out error);
  2217. if (error != 0)
  2218. throw new SocketException (error);
  2219. #if NET_2_0
  2220. islistening = true;
  2221. #endif
  2222. }
  2223. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2224. extern static bool Poll_internal (IntPtr socket, SelectMode mode, int timeout, out int error);
  2225. public bool Poll (int time_us, SelectMode mode)
  2226. {
  2227. if (disposed && closed)
  2228. throw new ObjectDisposedException (GetType ().ToString ());
  2229. if (mode != SelectMode.SelectRead &&
  2230. mode != SelectMode.SelectWrite &&
  2231. mode != SelectMode.SelectError)
  2232. throw new NotSupportedException ("'mode' parameter is not valid.");
  2233. int error;
  2234. bool result = Poll_internal (socket, mode, time_us, out error);
  2235. if (error != 0)
  2236. throw new SocketException (error);
  2237. if (mode == SelectMode.SelectWrite && result && !connected) {
  2238. /* Update the connected state; for
  2239. * non-blocking Connect()s this is
  2240. * when we can find out that the
  2241. * connect succeeded.
  2242. */
  2243. if ((int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error) == 0) {
  2244. connected = true;
  2245. }
  2246. }
  2247. return result;
  2248. }
  2249. /* This overload is needed as the async Connect method
  2250. * also needs to check the socket error status, but
  2251. * getsockopt(..., SO_ERROR) clears the error.
  2252. */
  2253. internal bool Poll (int time_us, SelectMode mode, out int socket_error)
  2254. {
  2255. if (disposed && closed)
  2256. throw new ObjectDisposedException (GetType ().ToString ());
  2257. if (mode != SelectMode.SelectRead &&
  2258. mode != SelectMode.SelectWrite &&
  2259. mode != SelectMode.SelectError)
  2260. throw new NotSupportedException ("'mode' parameter is not valid.");
  2261. int error;
  2262. bool result = Poll_internal (socket, mode, time_us, out error);
  2263. if (error != 0)
  2264. throw new SocketException (error);
  2265. socket_error = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
  2266. if (mode == SelectMode.SelectWrite && result) {
  2267. /* Update the connected state; for
  2268. * non-blocking Connect()s this is
  2269. * when we can find out that the
  2270. * connect succeeded.
  2271. */
  2272. if (socket_error == 0) {
  2273. connected = true;
  2274. }
  2275. }
  2276. return result;
  2277. }
  2278. #if NET_2_0
  2279. public bool ReceiveAsync (SocketAsyncEventArgs e)
  2280. {
  2281. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  2282. //
  2283. // LAME SPEC: the ArgumentException is never thrown, instead an NRE is
  2284. // thrown when e.Buffer and e.BufferList are null (works fine when one is
  2285. // set to a valid object)
  2286. if (disposed && closed)
  2287. throw new ObjectDisposedException (GetType ().ToString ());
  2288. // We do not support recv into multiple buffers yet
  2289. if (e.BufferList != null)
  2290. throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
  2291. e.DoOperation (SocketAsyncOperation.Receive, this);
  2292. // We always return true for now
  2293. return true;
  2294. }
  2295. #endif
  2296. public int Receive (byte [] buf)
  2297. {
  2298. if (disposed && closed)
  2299. throw new ObjectDisposedException (GetType ().ToString ());
  2300. if (buf == null)
  2301. throw new ArgumentNullException ("buf");
  2302. SocketError error;
  2303. int ret = Receive_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
  2304. if (error != SocketError.Success)
  2305. throw new SocketException ((int) error);
  2306. return ret;
  2307. }
  2308. public int Receive (byte [] buf, SocketFlags flags)
  2309. {
  2310. if (disposed && closed)
  2311. throw new ObjectDisposedException (GetType ().ToString ());
  2312. if (buf == null)
  2313. throw new ArgumentNullException ("buf");
  2314. SocketError error;
  2315. int ret = Receive_nochecks (buf, 0, buf.Length, flags, out error);
  2316. if (error != SocketError.Success) {
  2317. if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
  2318. throw new SocketException ((int) error, "Operation timed out.");
  2319. throw new SocketException ((int) error);
  2320. }
  2321. return ret;
  2322. }
  2323. public int Receive (byte [] buf, int size, SocketFlags flags)
  2324. {
  2325. if (disposed && closed)
  2326. throw new ObjectDisposedException (GetType ().ToString ());
  2327. if (buf == null)
  2328. throw new ArgumentNullException ("buf");
  2329. if (size < 0 || size > buf.Length)
  2330. throw new ArgumentOutOfRangeException ("size");
  2331. SocketError error;
  2332. int ret = Receive_nochecks (buf, 0, size, flags, out error);
  2333. if (error != SocketError.Success) {
  2334. if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
  2335. throw new SocketException ((int) error, "Operation timed out.");
  2336. throw new SocketException ((int) error);
  2337. }
  2338. return ret;
  2339. }
  2340. public int Receive (byte [] buf, int offset, int size, SocketFlags flags)
  2341. {
  2342. if (disposed && closed)
  2343. throw new ObjectDisposedException (GetType ().ToString ());
  2344. if (buf == null)
  2345. throw new ArgumentNullException ("buf");
  2346. if (offset < 0 || offset > buf.Length)
  2347. throw new ArgumentOutOfRangeException ("offset");
  2348. if (size < 0 || offset + size > buf.Length)
  2349. throw new ArgumentOutOfRangeException ("size");
  2350. SocketError error;
  2351. int ret = Receive_nochecks (buf, offset, size, flags, out error);
  2352. if (error != SocketError.Success) {
  2353. if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
  2354. throw new SocketException ((int) error, "Operation timed out.");
  2355. throw new SocketException ((int) error);
  2356. }
  2357. return ret;
  2358. }
  2359. #if NET_2_0
  2360. public int Receive (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
  2361. {
  2362. if (disposed && closed)
  2363. throw new ObjectDisposedException (GetType ().ToString ());
  2364. if (buf == null)
  2365. throw new ArgumentNullException ("buf");
  2366. if (offset < 0 || offset > buf.Length)
  2367. throw new ArgumentOutOfRangeException ("offset");
  2368. if (size < 0 || offset + size > buf.Length)
  2369. throw new ArgumentOutOfRangeException ("size");
  2370. return Receive_nochecks (buf, offset, size, flags, out error);
  2371. }
  2372. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  2373. private extern static int Receive_internal (IntPtr sock,
  2374. WSABUF[] bufarray,
  2375. SocketFlags flags,
  2376. out int error);
  2377. public int Receive (IList<ArraySegment<byte>> buffers)
  2378. {
  2379. int ret;
  2380. SocketError error;
  2381. ret = Receive (buffers, SocketFlags.None, out error);
  2382. if (error != SocketError.Success) {
  2383. throw new SocketException ((int)error);
  2384. }
  2385. return(ret);
  2386. }
  2387. [CLSCompliant (false)]
  2388. public int Receive (IList<ArraySegment<byte>> buffers,
  2389. SocketFlags socketFlags)
  2390. {
  2391. int ret;
  2392. SocketError error;
  2393. ret = Receive (buffers, socketFlags, out error);
  2394. if (error != SocketError.Success) {
  2395. throw new SocketException ((int)error);
  2396. }
  2397. return(ret);
  2398. }
  2399. [CLSCompliant (false)]
  2400. public int Receive (IList<ArraySegment<byte>> buffers,
  2401. SocketFlags socketFlags,
  2402. out SocketError errorCode)
  2403. {
  2404. if (buffers == null ||
  2405. buffers.Count == 0) {
  2406. throw new ArgumentNullException ("buffers");
  2407. }
  2408. if (disposed && closed) {
  2409. throw new ObjectDisposedException (GetType ().ToString ());
  2410. }
  2411. int numsegments = buffers.Count;
  2412. int nativeError;
  2413. int ret;
  2414. /* Only example I can find of sending a byte
  2415. * array reference directly into an internal
  2416. * call is in
  2417. * System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeSocket.cs,
  2418. * so taking a lead from that...
  2419. */
  2420. WSABUF[] bufarray = new WSABUF[numsegments];
  2421. GCHandle[] gch = new GCHandle[numsegments];
  2422. for(int i = 0; i < numsegments; i++) {
  2423. ArraySegment<byte> segment = buffers[i];
  2424. gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
  2425. bufarray[i].len = segment.Count;
  2426. bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
  2427. }
  2428. try {
  2429. ret = Receive_internal (socket, bufarray,
  2430. socketFlags,
  2431. out nativeError);
  2432. } finally {
  2433. for(int i = 0; i < numsegments; i++) {
  2434. if (gch[i].IsAllocated) {
  2435. gch[i].Free ();
  2436. }
  2437. }
  2438. }
  2439. errorCode = (SocketError)nativeError;
  2440. return(ret);
  2441. }
  2442. #endif
  2443. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2444. private extern static int Receive_internal(IntPtr sock,
  2445. byte[] buffer,
  2446. int offset,
  2447. int count,
  2448. SocketFlags flags,
  2449. out int error);
  2450. internal int Receive_nochecks (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
  2451. {
  2452. int nativeError;
  2453. int ret = Receive_internal (socket, buf, offset, size, flags, out nativeError);
  2454. error = (SocketError) nativeError;
  2455. if (error != SocketError.Success && error != SocketError.WouldBlock && error != SocketError.InProgress)
  2456. connected = false;
  2457. else
  2458. connected = true;
  2459. return ret;
  2460. }
  2461. #if NET_2_0
  2462. public bool ReceiveFromAsync (SocketAsyncEventArgs e)
  2463. {
  2464. if (disposed && closed)
  2465. throw new ObjectDisposedException (GetType ().ToString ());
  2466. // We do not support recv into multiple buffers yet
  2467. if (e.BufferList != null)
  2468. throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
  2469. if (e.RemoteEndPoint == null)
  2470. throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
  2471. e.DoOperation (SocketAsyncOperation.ReceiveFrom, this);
  2472. // We always return true for now
  2473. return true;
  2474. }
  2475. #endif
  2476. public int ReceiveFrom (byte [] buf, ref EndPoint remote_end)
  2477. {
  2478. if (disposed && closed)
  2479. throw new ObjectDisposedException (GetType ().ToString ());
  2480. if (buf == null)
  2481. throw new ArgumentNullException ("buf");
  2482. if (remote_end == null)
  2483. throw new ArgumentNullException ("remote_end");
  2484. return ReceiveFrom_nochecks (buf, 0, buf.Length, SocketFlags.None, ref remote_end);
  2485. }
  2486. public int ReceiveFrom (byte [] buf, SocketFlags flags, ref EndPoint remote_end)
  2487. {
  2488. if (disposed && closed)
  2489. throw new ObjectDisposedException (GetType ().ToString ());
  2490. if (buf == null)
  2491. throw new ArgumentNullException ("buf");
  2492. if (remote_end == null)
  2493. throw new ArgumentNullException ("remote_end");
  2494. return ReceiveFrom_nochecks (buf, 0, buf.Length, flags, ref remote_end);
  2495. }
  2496. public int ReceiveFrom (byte [] buf, int size, SocketFlags flags,
  2497. ref EndPoint remote_end)
  2498. {
  2499. if (disposed && closed)
  2500. throw new ObjectDisposedException (GetType ().ToString ());
  2501. if (buf == null)
  2502. throw new ArgumentNullException ("buf");
  2503. if (remote_end == null)
  2504. throw new ArgumentNullException ("remote_end");
  2505. if (size < 0 || size > buf.Length)
  2506. throw new ArgumentOutOfRangeException ("size");
  2507. return ReceiveFrom_nochecks (buf, 0, size, flags, ref remote_end);
  2508. }
  2509. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2510. private extern static int RecvFrom_internal(IntPtr sock,
  2511. byte[] buffer,
  2512. int offset,
  2513. int count,
  2514. SocketFlags flags,
  2515. ref SocketAddress sockaddr,
  2516. out int error);
  2517. public int ReceiveFrom (byte [] buf, int offset, int size, SocketFlags flags,
  2518. ref EndPoint remote_end)
  2519. {
  2520. if (disposed && closed)
  2521. throw new ObjectDisposedException (GetType ().ToString ());
  2522. if (buf == null)
  2523. throw new ArgumentNullException ("buf");
  2524. if (remote_end == null)
  2525. throw new ArgumentNullException ("remote_end");
  2526. if (offset < 0 || offset > buf.Length)
  2527. throw new ArgumentOutOfRangeException ("offset");
  2528. if (size < 0 || offset + size > buf.Length)
  2529. throw new ArgumentOutOfRangeException ("size");
  2530. return ReceiveFrom_nochecks (buf, offset, size, flags, ref remote_end);
  2531. }
  2532. internal int ReceiveFrom_nochecks (byte [] buf, int offset, int size, SocketFlags flags,
  2533. ref EndPoint remote_end)
  2534. {
  2535. int error;
  2536. return ReceiveFrom_nochecks_exc (buf, offset, size, flags, ref remote_end, true, out error);
  2537. }
  2538. internal int ReceiveFrom_nochecks_exc (byte [] buf, int offset, int size, SocketFlags flags,
  2539. ref EndPoint remote_end, bool throwOnError, out int error)
  2540. {
  2541. SocketAddress sockaddr = remote_end.Serialize();
  2542. int cnt = RecvFrom_internal (socket, buf, offset, size, flags, ref sockaddr, out error);
  2543. SocketError err = (SocketError) error;
  2544. if (err != 0) {
  2545. if (err != SocketError.WouldBlock && err != SocketError.InProgress)
  2546. connected = false;
  2547. else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
  2548. if (throwOnError)
  2549. throw new SocketException ((int) SocketError.TimedOut, "Operation timed out");
  2550. error = (int) SocketError.TimedOut;
  2551. return 0;
  2552. }
  2553. if (throwOnError)
  2554. throw new SocketException (error);
  2555. return 0;
  2556. }
  2557. connected = true;
  2558. #if NET_2_0
  2559. isbound = true;
  2560. #endif
  2561. // If sockaddr is null then we're a connection
  2562. // oriented protocol and should ignore the
  2563. // remote_end parameter (see MSDN
  2564. // documentation for Socket.ReceiveFrom(...) )
  2565. if ( sockaddr != null ) {
  2566. // Stupidly, EndPoint.Create() is an
  2567. // instance method
  2568. remote_end = remote_end.Create (sockaddr);
  2569. }
  2570. seed_endpoint = remote_end;
  2571. return cnt;
  2572. }
  2573. #if NET_2_0
  2574. [MonoTODO ("Not implemented")]
  2575. public bool ReceiveMessageFromAsync (SocketAsyncEventArgs e)
  2576. {
  2577. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  2578. if (disposed && closed)
  2579. throw new ObjectDisposedException (GetType ().ToString ());
  2580. throw new NotImplementedException ();
  2581. }
  2582. [MonoTODO ("Not implemented")]
  2583. public int ReceiveMessageFrom (byte[] buffer, int offset,
  2584. int size,
  2585. ref SocketFlags socketFlags,
  2586. ref EndPoint remoteEP,
  2587. out IPPacketInformation ipPacketInformation)
  2588. {
  2589. if (disposed && closed)
  2590. throw new ObjectDisposedException (GetType ().ToString ());
  2591. if (buffer == null)
  2592. throw new ArgumentNullException ("buffer");
  2593. if (remoteEP == null)
  2594. throw new ArgumentNullException ("remoteEP");
  2595. if (offset < 0 || offset > buffer.Length)
  2596. throw new ArgumentOutOfRangeException ("offset");
  2597. if (size < 0 || offset + size > buffer.Length)
  2598. throw new ArgumentOutOfRangeException ("size");
  2599. /* FIXME: figure out how we get hold of the
  2600. * IPPacketInformation
  2601. */
  2602. throw new NotImplementedException ();
  2603. }
  2604. [MonoTODO ("Not implemented")]
  2605. public bool SendPacketsAsync (SocketAsyncEventArgs e)
  2606. {
  2607. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  2608. if (disposed && closed)
  2609. throw new ObjectDisposedException (GetType ().ToString ());
  2610. throw new NotImplementedException ();
  2611. }
  2612. public bool SendAsync (SocketAsyncEventArgs e)
  2613. {
  2614. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  2615. if (disposed && closed)
  2616. throw new ObjectDisposedException (GetType ().ToString ());
  2617. if (e.Buffer == null && e.BufferList == null)
  2618. throw new ArgumentException ("Either e.Buffer or e.BufferList must be valid buffers.");
  2619. e.DoOperation (SocketAsyncOperation.Send, this);
  2620. // We always return true for now
  2621. return true;
  2622. }
  2623. #endif
  2624. public int Send (byte [] buf)
  2625. {
  2626. if (disposed && closed)
  2627. throw new ObjectDisposedException (GetType ().ToString ());
  2628. if (buf == null)
  2629. throw new ArgumentNullException ("buf");
  2630. SocketError error;
  2631. int ret = Send_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
  2632. if (error != SocketError.Success)
  2633. throw new SocketException ((int) error);
  2634. return ret;
  2635. }
  2636. public int Send (byte [] buf, SocketFlags flags)
  2637. {
  2638. if (disposed && closed)
  2639. throw new ObjectDisposedException (GetType ().ToString ());
  2640. if (buf == null)
  2641. throw new ArgumentNullException ("buf");
  2642. SocketError error;
  2643. int ret = Send_nochecks (buf, 0, buf.Length, flags, out error);
  2644. if (error != SocketError.Success)
  2645. throw new SocketException ((int) error);
  2646. return ret;
  2647. }
  2648. public int Send (byte [] buf, int size, SocketFlags flags)
  2649. {
  2650. if (disposed && closed)
  2651. throw new ObjectDisposedException (GetType ().ToString ());
  2652. if (buf == null)
  2653. throw new ArgumentNullException ("buf");
  2654. if (size < 0 || size > buf.Length)
  2655. throw new ArgumentOutOfRangeException ("size");
  2656. SocketError error;
  2657. int ret = Send_nochecks (buf, 0, size, flags, out error);
  2658. if (error != SocketError.Success)
  2659. throw new SocketException ((int) error);
  2660. return ret;
  2661. }
  2662. public int Send (byte [] buf, int offset, int size, SocketFlags flags)
  2663. {
  2664. if (disposed && closed)
  2665. throw new ObjectDisposedException (GetType ().ToString ());
  2666. if (buf == null)
  2667. throw new ArgumentNullException ("buffer");
  2668. if (offset < 0 || offset > buf.Length)
  2669. throw new ArgumentOutOfRangeException ("offset");
  2670. if (size < 0 || offset + size > buf.Length)
  2671. throw new ArgumentOutOfRangeException ("size");
  2672. SocketError error;
  2673. int ret = Send_nochecks (buf, offset, size, flags, out error);
  2674. if (error != SocketError.Success)
  2675. throw new SocketException ((int) error);
  2676. return ret;
  2677. }
  2678. #if NET_2_0
  2679. public int Send (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
  2680. {
  2681. if (disposed && closed)
  2682. throw new ObjectDisposedException (GetType ().ToString ());
  2683. if (buf == null)
  2684. throw new ArgumentNullException ("buffer");
  2685. if (offset < 0 || offset > buf.Length)
  2686. throw new ArgumentOutOfRangeException ("offset");
  2687. if (size < 0 || offset + size > buf.Length)
  2688. throw new ArgumentOutOfRangeException ("size");
  2689. return Send_nochecks (buf, offset, size, flags, out error);
  2690. }
  2691. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  2692. private extern static int Send_internal (IntPtr sock,
  2693. WSABUF[] bufarray,
  2694. SocketFlags flags,
  2695. out int error);
  2696. public int Send (IList<ArraySegment<byte>> buffers)
  2697. {
  2698. int ret;
  2699. SocketError error;
  2700. ret = Send (buffers, SocketFlags.None, out error);
  2701. if (error != SocketError.Success) {
  2702. throw new SocketException ((int)error);
  2703. }
  2704. return(ret);
  2705. }
  2706. public int Send (IList<ArraySegment<byte>> buffers,
  2707. SocketFlags socketFlags)
  2708. {
  2709. int ret;
  2710. SocketError error;
  2711. ret = Send (buffers, socketFlags, out error);
  2712. if (error != SocketError.Success) {
  2713. throw new SocketException ((int)error);
  2714. }
  2715. return(ret);
  2716. }
  2717. [CLSCompliant (false)]
  2718. public int Send (IList<ArraySegment<byte>> buffers,
  2719. SocketFlags socketFlags,
  2720. out SocketError errorCode)
  2721. {
  2722. if (disposed && closed) {
  2723. throw new ObjectDisposedException (GetType ().ToString ());
  2724. }
  2725. if (buffers == null) {
  2726. throw new ArgumentNullException ("buffers");
  2727. }
  2728. if (buffers.Count == 0) {
  2729. throw new ArgumentException ("Buffer is empty", "buffers");
  2730. }
  2731. int numsegments = buffers.Count;
  2732. int nativeError;
  2733. int ret;
  2734. WSABUF[] bufarray = new WSABUF[numsegments];
  2735. GCHandle[] gch = new GCHandle[numsegments];
  2736. for(int i = 0; i < numsegments; i++) {
  2737. ArraySegment<byte> segment = buffers[i];
  2738. gch[i] = GCHandle.Alloc (segment.Array, GCHandleType.Pinned);
  2739. bufarray[i].len = segment.Count;
  2740. bufarray[i].buf = Marshal.UnsafeAddrOfPinnedArrayElement (segment.Array, segment.Offset);
  2741. }
  2742. try {
  2743. ret = Send_internal (socket, bufarray,
  2744. socketFlags,
  2745. out nativeError);
  2746. } finally {
  2747. for(int i = 0; i < numsegments; i++) {
  2748. if (gch[i].IsAllocated) {
  2749. gch[i].Free ();
  2750. }
  2751. }
  2752. }
  2753. errorCode = (SocketError)nativeError;
  2754. return(ret);
  2755. }
  2756. #endif
  2757. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2758. private extern static int Send_internal(IntPtr sock,
  2759. byte[] buf, int offset,
  2760. int count,
  2761. SocketFlags flags,
  2762. out int error);
  2763. internal int Send_nochecks (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
  2764. {
  2765. if (size == 0) {
  2766. error = SocketError.Success;
  2767. return 0;
  2768. }
  2769. int nativeError;
  2770. int ret = Send_internal (socket, buf, offset, size, flags, out nativeError);
  2771. error = (SocketError)nativeError;
  2772. if (error != SocketError.Success && error != SocketError.WouldBlock && error != SocketError.InProgress)
  2773. connected = false;
  2774. else
  2775. connected = true;
  2776. return ret;
  2777. }
  2778. #if NET_2_0
  2779. [MonoTODO ("Not implemented")]
  2780. public void SendFile (string fileName)
  2781. {
  2782. if (disposed && closed)
  2783. throw new ObjectDisposedException (GetType ().ToString ());
  2784. if (!connected)
  2785. throw new NotSupportedException ();
  2786. if (!blocking)
  2787. throw new InvalidOperationException ();
  2788. if (!File.Exists (fileName))
  2789. throw new FileNotFoundException ();
  2790. /* FIXME: Implement TransmitFile */
  2791. throw new NotImplementedException ();
  2792. }
  2793. [MonoTODO ("Not implemented")]
  2794. public void SendFile (string fileName, byte[] preBuffer, byte[] postBuffer, TransmitFileOptions flags)
  2795. {
  2796. if (disposed && closed)
  2797. throw new ObjectDisposedException (GetType ().ToString ());
  2798. if (!connected)
  2799. throw new NotSupportedException ();
  2800. if (!blocking)
  2801. throw new InvalidOperationException ();
  2802. if (!File.Exists (fileName))
  2803. throw new FileNotFoundException ();
  2804. /* FIXME: Implement TransmitFile */
  2805. throw new NotImplementedException ();
  2806. }
  2807. public bool SendToAsync (SocketAsyncEventArgs e)
  2808. {
  2809. // NO check is made whether e != null in MS.NET (NRE is thrown in such case)
  2810. if (disposed && closed)
  2811. throw new ObjectDisposedException (GetType ().ToString ());
  2812. if (e.RemoteEndPoint == null)
  2813. throw new ArgumentNullException ("remoteEP", "Value cannot be null.");
  2814. e.DoOperation (SocketAsyncOperation.SendTo, this);
  2815. // We always return true for now
  2816. return true;
  2817. }
  2818. #endif
  2819. public int SendTo (byte [] buffer, EndPoint remote_end)
  2820. {
  2821. if (disposed && closed)
  2822. throw new ObjectDisposedException (GetType ().ToString ());
  2823. if (buffer == null)
  2824. throw new ArgumentNullException ("buffer");
  2825. if (remote_end == null)
  2826. throw new ArgumentNullException ("remote_end");
  2827. return SendTo_nochecks (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
  2828. }
  2829. public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
  2830. {
  2831. if (disposed && closed)
  2832. throw new ObjectDisposedException (GetType ().ToString ());
  2833. if (buffer == null)
  2834. throw new ArgumentNullException ("buffer");
  2835. if (remote_end == null)
  2836. throw new ArgumentNullException ("remote_end");
  2837. return SendTo_nochecks (buffer, 0, buffer.Length, flags, remote_end);
  2838. }
  2839. public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
  2840. {
  2841. if (disposed && closed)
  2842. throw new ObjectDisposedException (GetType ().ToString ());
  2843. if (buffer == null)
  2844. throw new ArgumentNullException ("buffer");
  2845. if (remote_end == null)
  2846. throw new ArgumentNullException ("remote_end");
  2847. if (size < 0 || size > buffer.Length)
  2848. throw new ArgumentOutOfRangeException ("size");
  2849. return SendTo_nochecks (buffer, 0, size, flags, remote_end);
  2850. }
  2851. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2852. private extern static int SendTo_internal(IntPtr sock,
  2853. byte[] buffer,
  2854. int offset,
  2855. int count,
  2856. SocketFlags flags,
  2857. SocketAddress sa,
  2858. out int error);
  2859. public int SendTo (byte [] buffer, int offset, int size, SocketFlags flags,
  2860. EndPoint remote_end)
  2861. {
  2862. if (disposed && closed)
  2863. throw new ObjectDisposedException (GetType ().ToString ());
  2864. if (buffer == null)
  2865. throw new ArgumentNullException ("buffer");
  2866. if (remote_end == null)
  2867. throw new ArgumentNullException("remote_end");
  2868. if (offset < 0 || offset > buffer.Length)
  2869. throw new ArgumentOutOfRangeException ("offset");
  2870. if (size < 0 || offset + size > buffer.Length)
  2871. throw new ArgumentOutOfRangeException ("size");
  2872. return SendTo_nochecks (buffer, offset, size, flags, remote_end);
  2873. }
  2874. internal int SendTo_nochecks (byte [] buffer, int offset, int size, SocketFlags flags,
  2875. EndPoint remote_end)
  2876. {
  2877. SocketAddress sockaddr = remote_end.Serialize ();
  2878. int ret, error;
  2879. ret = SendTo_internal (socket, buffer, offset, size, flags, sockaddr, out error);
  2880. SocketError err = (SocketError) error;
  2881. if (err != 0) {
  2882. if (err != SocketError.WouldBlock && err != SocketError.InProgress)
  2883. connected = false;
  2884. throw new SocketException (error);
  2885. }
  2886. connected = true;
  2887. #if NET_2_0
  2888. isbound = true;
  2889. #endif
  2890. seed_endpoint = remote_end;
  2891. return ret;
  2892. }
  2893. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2894. private extern static void SetSocketOption_internal (IntPtr socket, SocketOptionLevel level,
  2895. SocketOptionName name, object obj_val,
  2896. byte [] byte_val, int int_val,
  2897. out int error);
  2898. public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, byte[] opt_value)
  2899. {
  2900. if (disposed && closed)
  2901. throw new ObjectDisposedException (GetType ().ToString ());
  2902. int error;
  2903. SetSocketOption_internal(socket, level, name, null,
  2904. opt_value, 0, out error);
  2905. if (error != 0)
  2906. throw new SocketException (error);
  2907. }
  2908. public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, int opt_value)
  2909. {
  2910. if (disposed && closed)
  2911. throw new ObjectDisposedException (GetType ().ToString ());
  2912. int error;
  2913. SetSocketOption_internal(socket, level, name, null,
  2914. null, opt_value, out error);
  2915. if (error != 0)
  2916. throw new SocketException (error);
  2917. }
  2918. public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, object opt_value)
  2919. {
  2920. if (disposed && closed)
  2921. throw new ObjectDisposedException (GetType ().ToString ());
  2922. if (opt_value == null)
  2923. throw new ArgumentNullException("opt_value");
  2924. int error;
  2925. /* From MS documentation on SetSocketOption: "For an
  2926. * option with a Boolean data type, specify a nonzero
  2927. * value to enable the option, and a zero value to
  2928. * disable the option."
  2929. * Booleans are only handled in 2.0
  2930. */
  2931. if (opt_value is System.Boolean) {
  2932. #if NET_2_0
  2933. bool bool_val = (bool) opt_value;
  2934. int int_val = (bool_val) ? 1 : 0;
  2935. SetSocketOption_internal (socket, level, name, null, null, int_val, out error);
  2936. #else
  2937. throw new ArgumentException ("Use an integer 1 (true) or 0 (false) instead of a boolean.", "opt_value");
  2938. #endif
  2939. } else {
  2940. SetSocketOption_internal (socket, level, name, opt_value, null, 0, out error);
  2941. }
  2942. if (error != 0)
  2943. throw new SocketException (error);
  2944. }
  2945. #if NET_2_0
  2946. public void SetSocketOption (SocketOptionLevel level, SocketOptionName name, bool optionValue)
  2947. {
  2948. if (disposed && closed)
  2949. throw new ObjectDisposedException (GetType ().ToString ());
  2950. int error;
  2951. int int_val = (optionValue) ? 1 : 0;
  2952. SetSocketOption_internal (socket, level, name, null, null, int_val, out error);
  2953. if (error != 0)
  2954. throw new SocketException (error);
  2955. }
  2956. #endif
  2957. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  2958. private extern static void Shutdown_internal(IntPtr socket, SocketShutdown how, out int error);
  2959. public void Shutdown (SocketShutdown how)
  2960. {
  2961. if (disposed && closed)
  2962. throw new ObjectDisposedException (GetType ().ToString ());
  2963. int error;
  2964. Shutdown_internal (socket, how, out error);
  2965. if (error != 0)
  2966. throw new SocketException (error);
  2967. }
  2968. #if ONLY_1_1
  2969. public override int GetHashCode ()
  2970. {
  2971. // LAMESPEC:
  2972. // The socket is not suitable to serve as a hash code,
  2973. // because it will change during its lifetime, but
  2974. // this is how MS.NET 1.1 implemented this method.
  2975. return (int) socket;
  2976. }
  2977. #endif
  2978. protected virtual void Dispose (bool explicitDisposing)
  2979. {
  2980. if (disposed)
  2981. return;
  2982. disposed = true;
  2983. connected = false;
  2984. if ((int) socket != -1) {
  2985. int error;
  2986. closed = true;
  2987. IntPtr x = socket;
  2988. socket = (IntPtr) (-1);
  2989. Close_internal (x, out error);
  2990. if (blocking_thread != null) {
  2991. blocking_thread.Abort ();
  2992. blocking_thread = null;
  2993. }
  2994. if (error != 0)
  2995. throw new SocketException (error);
  2996. }
  2997. }
  2998. void IDisposable.Dispose ()
  2999. {
  3000. Dispose (true);
  3001. GC.SuppressFinalize (this);
  3002. }
  3003. ~Socket () {
  3004. Dispose (false);
  3005. }
  3006. }
  3007. }