TSocket.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Threading.Tasks;
  5. using Common.Logger;
  6. namespace TNet
  7. {
  8. public class TSocket
  9. {
  10. private readonly IPoller poller;
  11. private Socket socket;
  12. private readonly SocketAsyncEventArgs innArgs = new SocketAsyncEventArgs();
  13. private readonly SocketAsyncEventArgs outArgs = new SocketAsyncEventArgs();
  14. public TSocket(IPoller poller)
  15. {
  16. this.poller = poller;
  17. this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  18. this.innArgs.Completed += this.OnComplete;
  19. this.outArgs.Completed += this.OnComplete;
  20. }
  21. public IPoller Poller
  22. {
  23. get
  24. {
  25. return this.poller;
  26. }
  27. }
  28. public string RemoteAddress
  29. {
  30. get
  31. {
  32. return ((IPEndPoint) this.socket.RemoteEndPoint).Address + ":" +
  33. ((IPEndPoint) this.socket.RemoteEndPoint).Port;
  34. }
  35. }
  36. public Socket Socket
  37. {
  38. get
  39. {
  40. return this.socket;
  41. }
  42. }
  43. protected virtual void Dispose(bool disposing)
  44. {
  45. if (this.socket == null)
  46. {
  47. return;
  48. }
  49. if (disposing)
  50. {
  51. this.socket.Dispose();
  52. }
  53. this.socket = null;
  54. }
  55. ~TSocket()
  56. {
  57. this.Dispose(false);
  58. }
  59. public void Dispose()
  60. {
  61. this.Dispose(true);
  62. GC.SuppressFinalize(this);
  63. }
  64. public void Bind(string host, int port)
  65. {
  66. this.socket.Bind(new IPEndPoint(IPAddress.Parse(host), port));
  67. }
  68. public void Listen(int backlog)
  69. {
  70. this.socket.Listen(backlog);
  71. }
  72. private void OnComplete(object sender, SocketAsyncEventArgs e)
  73. {
  74. Action action;
  75. switch (e.LastOperation)
  76. {
  77. case SocketAsyncOperation.Accept:
  78. action = () => OnAcceptComplete(e);
  79. break;
  80. case SocketAsyncOperation.Connect:
  81. action = () => OnConnectComplete(e);
  82. break;
  83. case SocketAsyncOperation.Disconnect:
  84. action = () => OnDisconnectComplete(e);
  85. break;
  86. case SocketAsyncOperation.Receive:
  87. action = () => OnRecvComplete(e);
  88. break;
  89. case SocketAsyncOperation.Send:
  90. action = () => OnSendComplete(e);
  91. break;
  92. default:
  93. throw new ArgumentOutOfRangeException();
  94. }
  95. this.poller.Add(action);
  96. }
  97. public Task<bool> ConnectAsync(string host, int port)
  98. {
  99. var tcs = new TaskCompletionSource<bool>();
  100. this.outArgs.UserToken = tcs;
  101. this.outArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(host), port);
  102. if (!this.socket.ConnectAsync(this.outArgs))
  103. {
  104. OnConnectComplete(this.outArgs);
  105. }
  106. return tcs.Task;
  107. }
  108. private static void OnConnectComplete(SocketAsyncEventArgs e)
  109. {
  110. var tcs = (TaskCompletionSource<bool>) e.UserToken;
  111. e.UserToken = null;
  112. if (e.SocketError != SocketError.Success)
  113. {
  114. tcs.SetException(new Exception(string.Format("socket error: {0}", e.SocketError)));
  115. return;
  116. }
  117. tcs.SetResult(true);
  118. }
  119. public Task<bool> AcceptAsync(TSocket accpetSocket)
  120. {
  121. var tcs = new TaskCompletionSource<bool>();
  122. this.innArgs.UserToken = tcs;
  123. this.innArgs.AcceptSocket = accpetSocket.socket;
  124. if (!this.socket.AcceptAsync(this.innArgs))
  125. {
  126. OnAcceptComplete(this.innArgs);
  127. }
  128. return tcs.Task;
  129. }
  130. private static void OnAcceptComplete(SocketAsyncEventArgs e)
  131. {
  132. var tcs = (TaskCompletionSource<bool>) e.UserToken;
  133. e.UserToken = null;
  134. if (e.SocketError != SocketError.Success)
  135. {
  136. tcs.SetException(new Exception(string.Format("socket error: {0}", e.SocketError)));
  137. return;
  138. }
  139. tcs.SetResult(true);
  140. }
  141. public Task<int> RecvAsync(byte[] buffer, int offset, int count)
  142. {
  143. var tcs = new TaskCompletionSource<int>();
  144. this.innArgs.UserToken = tcs;
  145. this.innArgs.SetBuffer(buffer, offset, count);
  146. if (!this.socket.ReceiveAsync(this.innArgs))
  147. {
  148. OnRecvComplete(this.innArgs);
  149. }
  150. return tcs.Task;
  151. }
  152. private static void OnRecvComplete(SocketAsyncEventArgs e)
  153. {
  154. Log.Debug("OnRecvComplete: " + e.BytesTransferred);
  155. var tcs = (TaskCompletionSource<int>) e.UserToken;
  156. e.UserToken = null;
  157. if (e.SocketError != SocketError.Success)
  158. {
  159. tcs.SetException(new Exception(string.Format("socket error: {0}", e.SocketError)));
  160. return;
  161. }
  162. tcs.SetResult(e.BytesTransferred);
  163. }
  164. public Task<int> SendAsync(byte[] buffer, int offset, int count)
  165. {
  166. var tcs = new TaskCompletionSource<int>();
  167. this.outArgs.UserToken = tcs;
  168. this.outArgs.SetBuffer(buffer, offset, count);
  169. if (!this.socket.SendAsync(this.outArgs))
  170. {
  171. OnSendComplete(this.outArgs);
  172. }
  173. return tcs.Task;
  174. }
  175. private static void OnSendComplete(SocketAsyncEventArgs e)
  176. {
  177. var tcs = (TaskCompletionSource<int>) e.UserToken;
  178. e.UserToken = null;
  179. if (e.SocketError != SocketError.Success)
  180. {
  181. tcs.SetException(new Exception(string.Format("socket error: {0}", e.SocketError)));
  182. return;
  183. }
  184. tcs.SetResult(e.BytesTransferred);
  185. }
  186. public Task<bool> DisconnectAsync()
  187. {
  188. var tcs = new TaskCompletionSource<bool>();
  189. this.outArgs.UserToken = tcs;
  190. if (!this.socket.DisconnectAsync(this.outArgs))
  191. {
  192. OnDisconnectComplete(this.outArgs);
  193. }
  194. return tcs.Task;
  195. }
  196. private static void OnDisconnectComplete(SocketAsyncEventArgs e)
  197. {
  198. var tcs = (TaskCompletionSource<bool>) e.UserToken;
  199. e.UserToken = null;
  200. if (e.SocketError != SocketError.Success)
  201. {
  202. tcs.SetException(new Exception(string.Format("socket error: {0}", e.SocketError)));
  203. return;
  204. }
  205. tcs.SetResult(true);
  206. }
  207. }
  208. }