DebugSocket.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. using System.Net.Sockets;
  7. namespace ILRuntime.Runtime.Debugger
  8. {
  9. public class DebugSocket
  10. {
  11. private Socket _socket = null;
  12. private bool _ready = false;
  13. private const int MAX_BUFF_SIZE = 256 * 1024;
  14. private const int HEAD_SIZE = 8;
  15. private byte[] _headBuffer = new byte[HEAD_SIZE];
  16. private byte[] _sendBuffer = new byte[64 * 1024];
  17. //private MemoryPoolSafe<Package> _packagePool = new MemoryPoolSafe<Package>();
  18. //private Package _currPackage = null;
  19. private System.IO.MemoryStream _sendStream = null;
  20. BinaryWriter bw;
  21. const int RECV_BUFFER_SIZE = 1024;
  22. private MemoryStream recvBuffer = new MemoryStream();
  23. private int lastMsgLength = -1;
  24. private byte[] socketAsyncBuffer = new byte[RECV_BUFFER_SIZE];
  25. private SocketAsyncEventArgs saeArgs;
  26. private object socketLockObj = new object();
  27. private byte[] _sendHeaderBuffer = new byte[HEAD_SIZE];
  28. public bool Disconnected { get { return _socket == null || !_socket.Connected; } }
  29. public Action OnConnect { get; set; }
  30. public Action OnConnectFailed { get; set; }
  31. public Action OnClose { get; set; }
  32. public Action<DebugMessageType, byte[]> OnReciveMessage { get; set; }
  33. public DebugSocket()
  34. {
  35. _sendStream = new System.IO.MemoryStream(_sendBuffer);
  36. bw = new BinaryWriter(_sendStream);
  37. }
  38. public DebugSocket(Socket _socket)
  39. : this()
  40. {
  41. this._socket = _socket;
  42. BeginReceive();
  43. _ready = true;
  44. }
  45. public void Connect(string ip, int port)
  46. {
  47. Close();
  48. Socket socket;
  49. socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  50. socket.BeginConnect(ip, port, new AsyncCallback(onConnected), this);
  51. _socket = socket;
  52. _ready = false;
  53. }
  54. private void AsyncRecv_Completed(object sender, SocketAsyncEventArgs e)
  55. {
  56. if (e.SocketError == SocketError.Success && e.BytesTransferred > 0)
  57. {
  58. try
  59. {
  60. ReceivePayload(e.Buffer, e.BytesTransferred);
  61. }
  62. catch (Exception)
  63. {
  64. Close();
  65. return;
  66. }
  67. }
  68. else
  69. {
  70. Close();
  71. return;
  72. }
  73. try
  74. {
  75. //继续接受数据
  76. if (!_socket.ReceiveAsync(saeArgs))
  77. {
  78. AsyncRecv_Completed(null, saeArgs);
  79. }
  80. }
  81. catch (Exception ex)
  82. {
  83. Close();
  84. throw ex;
  85. }
  86. }
  87. private void ReceivePayload(byte[] data, int length)
  88. {
  89. if (_socket == null)
  90. return;
  91. if (!_socket.Connected)
  92. {
  93. Close();
  94. return;
  95. }
  96. //接受数据并拼接成message
  97. byte[] msgBuff;
  98. //写入缓存
  99. recvBuffer.Position = recvBuffer.Length;
  100. recvBuffer.Write(data, 0, length);
  101. //如果长度有错,返回
  102. if (lastMsgLength < 0 && recvBuffer.Length < 4)
  103. {
  104. msgBuff = null;
  105. return;
  106. }
  107. recvBuffer.Position = 0;
  108. BinaryReader br = new BinaryReader(recvBuffer);
  109. //读取消息长度
  110. if (lastMsgLength < 0)
  111. {
  112. lastMsgLength = br.ReadInt32() - 4;
  113. if (lastMsgLength > MAX_BUFF_SIZE)
  114. {
  115. Close();
  116. throw new Exception("Too long package length!");
  117. }
  118. }
  119. int remaining = (int)(recvBuffer.Length - recvBuffer.Position);
  120. //消息已经完整
  121. while (remaining >= lastMsgLength && lastMsgLength > 0)
  122. {
  123. //读取一条消息
  124. int type = br.ReadInt32();
  125. msgBuff = br.ReadBytes(lastMsgLength - 4);
  126. try
  127. {
  128. if (OnReciveMessage != null)
  129. OnReciveMessage((DebugMessageType)type, msgBuff);
  130. }
  131. catch(Exception ex)
  132. {
  133. Console.WriteLine(ex.ToString());
  134. }
  135. lastMsgLength = -1;
  136. remaining = (int)(recvBuffer.Length - recvBuffer.Position);
  137. //保留剩余数据
  138. if (remaining >= 4)
  139. {
  140. lastMsgLength = br.ReadInt32() - 4;
  141. remaining -= 4;
  142. if (lastMsgLength > MAX_BUFF_SIZE)
  143. {
  144. Close();
  145. throw new Exception("Too long package length!");
  146. }
  147. }
  148. }
  149. remaining = (int)(recvBuffer.Length - recvBuffer.Position);
  150. if (remaining > 0)
  151. {
  152. byte[] buffer = recvBuffer.GetBuffer();
  153. Array.Copy(buffer, recvBuffer.Position, buffer, 0, remaining);
  154. }
  155. recvBuffer.Position = 0;
  156. recvBuffer.SetLength(remaining);
  157. }
  158. private void onConnected(IAsyncResult result)
  159. {
  160. if (_socket.Connected)
  161. {
  162. _socket.EndConnect(result);
  163. BeginReceive();
  164. if (OnConnect != null)
  165. OnConnect();
  166. //ReceiveOnce();
  167. }
  168. else
  169. {
  170. if (OnConnectFailed != null)
  171. OnConnectFailed();
  172. }
  173. }
  174. void BeginReceive()
  175. {
  176. saeArgs = new SocketAsyncEventArgs();
  177. saeArgs.Completed += AsyncRecv_Completed;
  178. saeArgs.SetBuffer(socketAsyncBuffer, 0, socketAsyncBuffer.Length);
  179. _socket.ReceiveAsync(saeArgs);
  180. _ready = true;
  181. }
  182. //len type msg
  183. public void Send(DebugMessageType type, byte[] buffer, int len)
  184. {
  185. if (!_ready)
  186. return;
  187. //timeStamp = UnityEngine.Time.realtimeSinceStartup;
  188. _sendStream.Position = 0;
  189. bw.Write(len + HEAD_SIZE);
  190. bw.Write((int)type);
  191. bw.Write(buffer, 0, len);
  192. int totalLen = (int)_sendStream.Position;
  193. RawSend(_socket, _sendBuffer, totalLen);
  194. //_socket.Send(_sendBuffer, len, SocketFlags.None);
  195. }
  196. private void RawSend(Socket sock, byte[] buf, int end)
  197. {
  198. if (sock == null)
  199. return;
  200. if (end < 0)
  201. end = buf.Length;
  202. sock.Send(buf, end, SocketFlags.None);
  203. }
  204. public void Close()
  205. {
  206. if (_socket == null || !_ready)
  207. return;
  208. if (saeArgs != null)
  209. saeArgs.Dispose();
  210. _socket.Close();
  211. _socket = null;
  212. _ready = false;
  213. if (OnClose != null)
  214. {
  215. OnClose();
  216. }
  217. }
  218. }
  219. }