123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.IO;
- using System.Net.Sockets;
- namespace ILRuntime.Runtime.Debugger
- {
- public class DebugSocket
- {
- private Socket _socket = null;
- private bool _ready = false;
- private const int MAX_BUFF_SIZE = 256 * 1024;
- private const int HEAD_SIZE = 8;
- private byte[] _headBuffer = new byte[HEAD_SIZE];
- private byte[] _sendBuffer = new byte[64 * 1024];
- //private MemoryPoolSafe<Package> _packagePool = new MemoryPoolSafe<Package>();
- //private Package _currPackage = null;
- private System.IO.MemoryStream _sendStream = null;
- BinaryWriter bw;
- const int RECV_BUFFER_SIZE = 1024;
- private MemoryStream recvBuffer = new MemoryStream();
- private int lastMsgLength = -1;
- private byte[] socketAsyncBuffer = new byte[RECV_BUFFER_SIZE];
- private SocketAsyncEventArgs saeArgs;
- private object socketLockObj = new object();
- private byte[] _sendHeaderBuffer = new byte[HEAD_SIZE];
- public bool Disconnected { get { return _socket == null || !_socket.Connected; } }
- public Action OnConnect { get; set; }
- public Action OnConnectFailed { get; set; }
- public Action OnClose { get; set; }
- public Action<DebugMessageType, byte[]> OnReciveMessage { get; set; }
- public DebugSocket()
- {
- _sendStream = new System.IO.MemoryStream(_sendBuffer);
- bw = new BinaryWriter(_sendStream);
- }
- public DebugSocket(Socket _socket)
- : this()
- {
- this._socket = _socket;
- BeginReceive();
- _ready = true;
- }
- public void Connect(string ip, int port)
- {
- Close();
- Socket socket;
- socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- socket.BeginConnect(ip, port, new AsyncCallback(onConnected), this);
- _socket = socket;
- _ready = false;
- }
- private void AsyncRecv_Completed(object sender, SocketAsyncEventArgs e)
- {
- if (e.SocketError == SocketError.Success && e.BytesTransferred > 0)
- {
- try
- {
- ReceivePayload(e.Buffer, e.BytesTransferred);
- }
- catch (Exception)
- {
- Close();
- return;
- }
- }
- else
- {
- Close();
- return;
- }
- try
- {
- //继续接受数据
- if (!_socket.ReceiveAsync(saeArgs))
- {
- AsyncRecv_Completed(null, saeArgs);
- }
- }
- catch (Exception ex)
- {
- Close();
- throw ex;
- }
- }
- private void ReceivePayload(byte[] data, int length)
- {
- if (_socket == null)
- return;
- if (!_socket.Connected)
- {
- Close();
- return;
- }
- //接受数据并拼接成message
- byte[] msgBuff;
- //写入缓存
- recvBuffer.Position = recvBuffer.Length;
- recvBuffer.Write(data, 0, length);
- //如果长度有错,返回
- if (lastMsgLength < 0 && recvBuffer.Length < 4)
- {
- msgBuff = null;
- return;
- }
- recvBuffer.Position = 0;
- BinaryReader br = new BinaryReader(recvBuffer);
- //读取消息长度
- if (lastMsgLength < 0)
- {
- lastMsgLength = br.ReadInt32() - 4;
- if (lastMsgLength > MAX_BUFF_SIZE)
- {
- Close();
- throw new Exception("Too long package length!");
- }
- }
- int remaining = (int)(recvBuffer.Length - recvBuffer.Position);
- //消息已经完整
- while (remaining >= lastMsgLength && lastMsgLength > 0)
- {
- //读取一条消息
- int type = br.ReadInt32();
- msgBuff = br.ReadBytes(lastMsgLength - 4);
- try
- {
- if (OnReciveMessage != null)
- OnReciveMessage((DebugMessageType)type, msgBuff);
- }
- catch(Exception ex)
- {
- Console.WriteLine(ex.ToString());
- }
- lastMsgLength = -1;
- remaining = (int)(recvBuffer.Length - recvBuffer.Position);
- //保留剩余数据
- if (remaining >= 4)
- {
- lastMsgLength = br.ReadInt32() - 4;
- remaining -= 4;
- if (lastMsgLength > MAX_BUFF_SIZE)
- {
- Close();
- throw new Exception("Too long package length!");
- }
- }
- }
- remaining = (int)(recvBuffer.Length - recvBuffer.Position);
- if (remaining > 0)
- {
- byte[] buffer = recvBuffer.GetBuffer();
- Array.Copy(buffer, recvBuffer.Position, buffer, 0, remaining);
- }
- recvBuffer.Position = 0;
- recvBuffer.SetLength(remaining);
- }
- private void onConnected(IAsyncResult result)
- {
- if (_socket.Connected)
- {
- _socket.EndConnect(result);
- BeginReceive();
- if (OnConnect != null)
- OnConnect();
- //ReceiveOnce();
- }
- else
- {
- if (OnConnectFailed != null)
- OnConnectFailed();
- }
- }
- void BeginReceive()
- {
- saeArgs = new SocketAsyncEventArgs();
- saeArgs.Completed += AsyncRecv_Completed;
- saeArgs.SetBuffer(socketAsyncBuffer, 0, socketAsyncBuffer.Length);
- _socket.ReceiveAsync(saeArgs);
- _ready = true;
- }
- //len type msg
- public void Send(DebugMessageType type, byte[] buffer, int len)
- {
- if (!_ready)
- return;
- //timeStamp = UnityEngine.Time.realtimeSinceStartup;
- _sendStream.Position = 0;
- bw.Write(len + HEAD_SIZE);
- bw.Write((int)type);
- bw.Write(buffer, 0, len);
- int totalLen = (int)_sendStream.Position;
- RawSend(_socket, _sendBuffer, totalLen);
- //_socket.Send(_sendBuffer, len, SocketFlags.None);
- }
- private void RawSend(Socket sock, byte[] buf, int end)
- {
- if (sock == null)
- return;
- if (end < 0)
- end = buf.Length;
- sock.Send(buf, end, SocketFlags.None);
- }
- public void Close()
- {
- if (_socket == null || !_ready)
- return;
- if (saeArgs != null)
- saeArgs.Dispose();
- _socket.Close();
- _socket = null;
- _ready = false;
- if (OnClose != null)
- {
- OnClose();
- }
- }
- }
- }
|