using System; using System.Net; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; //IP Range Updater namespace Mistox.Client { public class mTCPClient : IDisposable { TcpClient _connection; MistoxClient _parent; public mTCPClient( MistoxClient parent, IPEndPoint ServerAddress ) { _connection = new TcpClient( AddressFamily.InterNetwork ); _connection.NoDelay = true; _connection.Connect( ServerAddress ); _parent.InvokeOnServerConnected(); Thread RThread = new Thread(async () => { await ReceiveThread(); }); RThread.Start(); } async Task ReceiveThread() { using( NetworkStream ns = _connection.GetStream() ) { try { byte[] headerBuffer = new byte[DataPacket.HeaderLength]; byte[] payloadBuffer = new byte[65535]; // Upper limit for safety while( _parent.Alive ) { // Read the header off await ns.ReadExactlyAsync(headerBuffer, 0, 3); // Parse the header byte packetbyte = headerBuffer[0]; ushort dataLength = (ushort)((headerBuffer[1] << 8) | headerBuffer[2]); // Make sure the data looks valid if (dataLength > payloadBuffer.Length) { throw new Exception("Incoming TCP payload is too large for the pre-allocated buffer."); } // Read off the data await ns.ReadExactlyAsync(payloadBuffer, 0, dataLength); // Create the dataobject dynamic dataobject = DataPacket.Deserialize( packetbyte, dataLength, payloadBuffer.AsMemory(DataPacket.HeaderLength, dataLength) ); // Return the object _parent.InvokeOnReceived(dataobject); } } catch (Exception e) { _parent.Alive = false; Dispose(); Console.WriteLine("TCP Receive exception: " + e.Message); } } } public async Task Send(T packet) { byte[] data = DataPacket.Serialize( packet ); await _connection.GetStream().WriteAsync( data, 0, data.Length ); } public void Dispose() { _parent.InvokeOnServerDisconnected(); _connection.Close(); _connection = null; } } }