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 Server; public mTCPClient( IPEndPoint ServerAddress ) { Server = new TcpClient( AddressFamily.InterNetwork ); Server.NoDelay = true; Server.Connect( ServerAddress ); ClientInterface.ServerClientInstance.InvokeOnServerConnected(); Thread RThread = new Thread(async () => { await ReceiveThread(); }); RThread.Start(); } async Task ReceiveThread() { using( NetworkStream ns = Server.GetStream() ) { try { byte[] headerBuffer = new byte[DataPacket.HeaderLength]; byte[] payloadBuffer = new byte[65535]; // Upper limit for safety while( ClientInterface.ServerClientInstance.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 ClientInterface.ServerClientInstance.InvokeOnReceived(dataobject); } } catch (Exception e) { ClientInterface.ServerClientInstance.Alive = false; Dispose(); Console.WriteLine("TCP Receive exception: " + e.Message); } } } public async Task Send(T packet) { byte[] data = DataPacket.Serialize( packet ); await Server.GetStream().WriteAsync( data, 0, data.Length ); } public void Dispose() { ClientInterface.ServerClientInstance.InvokeOnServerDisconnected(); Server.Close(); Server = null; } } }