SocketTaskExtensions.cs 11 KB

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