SocketTaskExtensions.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections.Generic;
  5. using System.Threading.Tasks;
  6. namespace System.Net.Sockets
  7. {
  8. public static class SocketTaskExtensions
  9. {
  10. public static Task<Socket> AcceptAsync(this Socket socket)
  11. {
  12. return Task<Socket>.Factory.FromAsync(
  13. (callback, state) => ((Socket)state).BeginAccept(callback, state),
  14. asyncResult => ((Socket)asyncResult.AsyncState).EndAccept(asyncResult),
  15. state: socket);
  16. }
  17. public static Task<Socket> AcceptAsync(this Socket socket, Socket acceptSocket)
  18. {
  19. const int ReceiveSize = 0;
  20. return Task<Socket>.Factory.FromAsync(
  21. (socketForAccept, receiveSize, callback, state) => ((Socket)state).BeginAccept(socketForAccept, receiveSize, callback, state),
  22. asyncResult => ((Socket)asyncResult.AsyncState).EndAccept(asyncResult),
  23. acceptSocket,
  24. ReceiveSize,
  25. state: socket);
  26. }
  27. public static Task ConnectAsync(this Socket socket, EndPoint remoteEP)
  28. {
  29. return Task.Factory.FromAsync(
  30. (targetEndPoint, callback, state) => ((Socket)state).BeginConnect(targetEndPoint, callback, state),
  31. asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
  32. remoteEP,
  33. state: socket);
  34. }
  35. public static Task ConnectAsync(this Socket socket, IPAddress address, int port)
  36. {
  37. return Task.Factory.FromAsync(
  38. (targetAddress, targetPort, callback, state) => ((Socket)state).BeginConnect(targetAddress, targetPort, callback, state),
  39. asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
  40. address,
  41. port,
  42. state: socket);
  43. }
  44. public static Task ConnectAsync(this Socket socket, IPAddress[] addresses, int port)
  45. {
  46. return Task.Factory.FromAsync(
  47. (targetAddresses, targetPort, callback, state) => ((Socket)state).BeginConnect(targetAddresses, targetPort, callback, state),
  48. asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
  49. addresses,
  50. port,
  51. state: socket);
  52. }
  53. public static Task ConnectAsync(this Socket socket, string host, int port)
  54. {
  55. return Task.Factory.FromAsync(
  56. (targetHost, targetPort, callback, state) => ((Socket)state).BeginConnect(targetHost, targetPort, callback, state),
  57. asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
  58. host,
  59. port,
  60. state: socket);
  61. }
  62. public static Task<int> ReceiveAsync(this Socket socket, ArraySegment<byte> buffer, SocketFlags socketFlags)
  63. {
  64. return Task<int>.Factory.FromAsync(
  65. (targetBuffer, flags, callback, state) => ((Socket)state).BeginReceive(
  66. targetBuffer.Array,
  67. targetBuffer.Offset,
  68. targetBuffer.Count,
  69. flags,
  70. callback,
  71. state),
  72. asyncResult => ((Socket)asyncResult.AsyncState).EndReceive(asyncResult),
  73. buffer,
  74. socketFlags,
  75. state: socket);
  76. }
  77. public static Task<int> ReceiveAsync(
  78. this Socket socket,
  79. IList<ArraySegment<byte>> buffers,
  80. SocketFlags socketFlags)
  81. {
  82. return Task<int>.Factory.FromAsync(
  83. (targetBuffers, flags, callback, state) => ((Socket)state).BeginReceive(targetBuffers, flags, callback, state),
  84. asyncResult => ((Socket)asyncResult.AsyncState).EndReceive(asyncResult),
  85. buffers,
  86. socketFlags,
  87. state: socket);
  88. }
  89. public static Task<SocketReceiveFromResult> ReceiveFromAsync(
  90. this Socket socket,
  91. ArraySegment<byte> buffer,
  92. SocketFlags socketFlags,
  93. EndPoint remoteEndPoint)
  94. {
  95. object[] packedArguments = new object[] { socket, remoteEndPoint };
  96. return Task<SocketReceiveFromResult>.Factory.FromAsync(
  97. (targetBuffer, flags, callback, state) =>
  98. {
  99. var arguments = (object[])state;
  100. var s = (Socket)arguments[0];
  101. var e = (EndPoint)arguments[1];
  102. IAsyncResult result = s.BeginReceiveFrom(
  103. targetBuffer.Array,
  104. targetBuffer.Offset,
  105. targetBuffer.Count,
  106. flags,
  107. ref e,
  108. callback,
  109. state);
  110. arguments[1] = e;
  111. return result;
  112. },
  113. asyncResult =>
  114. {
  115. var arguments = (object[])asyncResult.AsyncState;
  116. var s = (Socket)arguments[0];
  117. var e = (EndPoint)arguments[1];
  118. int bytesReceived = s.EndReceiveFrom(asyncResult, ref e);
  119. return new SocketReceiveFromResult()
  120. {
  121. ReceivedBytes = bytesReceived,
  122. RemoteEndPoint = e
  123. };
  124. },
  125. buffer,
  126. socketFlags,
  127. state: packedArguments);
  128. }
  129. public static Task<SocketReceiveMessageFromResult> ReceiveMessageFromAsync(
  130. this Socket socket,
  131. ArraySegment<byte> buffer,
  132. SocketFlags socketFlags,
  133. EndPoint remoteEndPoint)
  134. {
  135. object[] packedArguments = new object[] { socket, socketFlags, remoteEndPoint };
  136. return Task<SocketReceiveMessageFromResult>.Factory.FromAsync(
  137. (targetBuffer, callback, state) =>
  138. {
  139. var arguments = (object[])state;
  140. var s = (Socket)arguments[0];
  141. var f = (SocketFlags)arguments[1];
  142. var e = (EndPoint)arguments[2];
  143. IAsyncResult result = s.BeginReceiveMessageFrom(
  144. targetBuffer.Array,
  145. targetBuffer.Offset,
  146. targetBuffer.Count,
  147. f,
  148. ref e,
  149. callback,
  150. state);
  151. arguments[2] = e;
  152. return result;
  153. },
  154. asyncResult =>
  155. {
  156. var arguments = (object[])asyncResult.AsyncState;
  157. var s = (Socket)arguments[0];
  158. var f = (SocketFlags)arguments[1];
  159. var e = (EndPoint)arguments[2];
  160. IPPacketInformation ipPacket;
  161. int bytesReceived = s.EndReceiveMessageFrom(
  162. asyncResult,
  163. ref f,
  164. ref e,
  165. out ipPacket);
  166. return new SocketReceiveMessageFromResult()
  167. {
  168. PacketInformation = ipPacket,
  169. ReceivedBytes = bytesReceived,
  170. RemoteEndPoint = e,
  171. SocketFlags = f
  172. };
  173. },
  174. buffer,
  175. state: packedArguments);
  176. }
  177. public static Task<int> SendAsync(this Socket socket, ArraySegment<byte> buffer, SocketFlags socketFlags)
  178. {
  179. return Task<int>.Factory.FromAsync(
  180. (targetBuffer, flags, callback, state) => ((Socket)state).BeginSend(
  181. targetBuffer.Array,
  182. targetBuffer.Offset,
  183. targetBuffer.Count,
  184. flags,
  185. callback,
  186. state),
  187. asyncResult => ((Socket)asyncResult.AsyncState).EndSend(asyncResult),
  188. buffer,
  189. socketFlags,
  190. state: socket);
  191. }
  192. public static Task<int> SendAsync(
  193. this Socket socket,
  194. IList<ArraySegment<byte>> buffers,
  195. SocketFlags socketFlags)
  196. {
  197. return Task<int>.Factory.FromAsync(
  198. (targetBuffers, flags, callback, state) => ((Socket)state).BeginSend(targetBuffers, flags, callback, state),
  199. asyncResult => ((Socket)asyncResult.AsyncState).EndSend(asyncResult),
  200. buffers,
  201. socketFlags,
  202. state: socket);
  203. }
  204. public static Task<int> SendToAsync(
  205. this Socket socket,
  206. ArraySegment<byte> buffer,
  207. SocketFlags socketFlags,
  208. EndPoint remoteEP)
  209. {
  210. return Task<int>.Factory.FromAsync(
  211. (targetBuffer, flags, endPoint, callback, state) => ((Socket)state).BeginSendTo(
  212. targetBuffer.Array,
  213. targetBuffer.Offset,
  214. targetBuffer.Count,
  215. flags,
  216. endPoint,
  217. callback,
  218. state),
  219. asyncResult => ((Socket)asyncResult.AsyncState).EndSendTo(asyncResult),
  220. buffer,
  221. socketFlags,
  222. remoteEP,
  223. state: socket);
  224. }
  225. }
  226. }