TSocket.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Threading.Tasks;
  5. namespace TNet
  6. {
  7. public class TSocket
  8. {
  9. private IPoller poller;
  10. private readonly Socket socket;
  11. private readonly SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs();
  12. public TSocket(IPoller poller)
  13. {
  14. this.poller = poller;
  15. this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  16. this.socketAsyncEventArgs.Completed += this.OnComplete;
  17. }
  18. public Socket Socket
  19. {
  20. get
  21. {
  22. return this.socket;
  23. }
  24. }
  25. public void Dispose()
  26. {
  27. if (this.poller == null)
  28. {
  29. return;
  30. }
  31. this.socket.Dispose();
  32. this.poller = null;
  33. }
  34. public void Bind(string host, int port)
  35. {
  36. this.socket.Bind(new IPEndPoint(IPAddress.Parse(host), port));
  37. }
  38. public void Listen(int backlog)
  39. {
  40. this.socket.Listen(backlog);
  41. }
  42. private void OnComplete(object sender, SocketAsyncEventArgs e)
  43. {
  44. Action action;
  45. switch (e.LastOperation)
  46. {
  47. case SocketAsyncOperation.Accept:
  48. action = () => OnAcceptComplete(e);
  49. e.AcceptSocket = null;
  50. break;
  51. case SocketAsyncOperation.Connect:
  52. action = () => OnConnectComplete(e);
  53. break;
  54. case SocketAsyncOperation.Disconnect:
  55. action = () => OnDisconnectComplete(e);
  56. break;
  57. case SocketAsyncOperation.Receive:
  58. action = () => OnRecvComplete(e);
  59. break;
  60. case SocketAsyncOperation.Send:
  61. action = () => OnSendComplete(e);
  62. break;
  63. default:
  64. throw new ArgumentOutOfRangeException();
  65. }
  66. this.poller.Add(action);
  67. }
  68. public Task<bool> ConnectAsync(string host, int port)
  69. {
  70. var tcs = new TaskCompletionSource<bool>();
  71. this.socketAsyncEventArgs.UserToken = tcs;
  72. this.socketAsyncEventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(host), port);
  73. if (!this.socket.ConnectAsync(this.socketAsyncEventArgs))
  74. {
  75. this.poller.Add(() => { OnConnectComplete(this.socketAsyncEventArgs); });
  76. }
  77. return tcs.Task;
  78. }
  79. private static void OnConnectComplete(SocketAsyncEventArgs e)
  80. {
  81. var tcs = (TaskCompletionSource<bool>)e.UserToken;
  82. tcs.SetResult(true);
  83. }
  84. public Task<bool> AcceptAsync(TSocket accpetSocket)
  85. {
  86. var tcs = new TaskCompletionSource<bool>();
  87. this.socketAsyncEventArgs.UserToken = tcs;
  88. this.socketAsyncEventArgs.AcceptSocket = accpetSocket.socket;
  89. if (!this.socket.AcceptAsync(this.socketAsyncEventArgs))
  90. {
  91. Action action = () => OnAcceptComplete(this.socketAsyncEventArgs);
  92. this.poller.Add(action);
  93. }
  94. return tcs.Task;
  95. }
  96. private static void OnAcceptComplete(SocketAsyncEventArgs e)
  97. {
  98. var tcs = (TaskCompletionSource<bool>)e.UserToken;
  99. tcs.SetResult(true);
  100. }
  101. public Task<int> RecvAsync(byte[] buffer, int offset, int count)
  102. {
  103. var tcs = new TaskCompletionSource<int>();
  104. this.socketAsyncEventArgs.UserToken = tcs;
  105. this.socketAsyncEventArgs.SetBuffer(buffer, offset, count);
  106. if (!this.socket.ReceiveAsync(this.socketAsyncEventArgs))
  107. {
  108. Action action = () => OnRecvComplete(this.socketAsyncEventArgs);
  109. this.poller.Add(action);
  110. }
  111. return tcs.Task;
  112. }
  113. private static void OnRecvComplete(SocketAsyncEventArgs e)
  114. {
  115. var tcs = (TaskCompletionSource<int>)e.UserToken;
  116. tcs.SetResult(e.BytesTransferred);
  117. }
  118. public Task<int> SendAsync(byte[] buffer, int offset, int count)
  119. {
  120. var tcs = new TaskCompletionSource<int>();
  121. this.socketAsyncEventArgs.UserToken = tcs;
  122. this.socketAsyncEventArgs.SetBuffer(buffer, offset, count);
  123. if (!this.socket.SendAsync(this.socketAsyncEventArgs))
  124. {
  125. Action action = () => OnSendComplete(this.socketAsyncEventArgs);
  126. this.poller.Add(action);
  127. }
  128. return tcs.Task;
  129. }
  130. private static void OnSendComplete(SocketAsyncEventArgs e)
  131. {
  132. var tcs = (TaskCompletionSource<int>)e.UserToken;
  133. tcs.SetResult(e.BytesTransferred);
  134. }
  135. public Task<bool> DisconnectAsync()
  136. {
  137. var tcs = new TaskCompletionSource<bool>();
  138. this.socketAsyncEventArgs.UserToken = tcs;
  139. if (!this.socket.DisconnectAsync(this.socketAsyncEventArgs))
  140. {
  141. Action action = () => OnDisconnectComplete(this.socketAsyncEventArgs);
  142. this.poller.Add(action);
  143. }
  144. return tcs.Task;
  145. }
  146. private static void OnDisconnectComplete(SocketAsyncEventArgs e)
  147. {
  148. var tcs = (TaskCompletionSource<bool>)e.UserToken;
  149. tcs.SetResult(true);
  150. }
  151. }
  152. }