using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; namespace Filter.Networking.Instances { internal abstract class Client : IDisposable { public Socket ClientSocket; private IPEndPoint ClientEndPoint; private NetworkStream ClientStream; private byte[] ClientBuffer; public string RemoteAddress; public int RemotePort; public int IsConnected; public Client(IPAddress ConnectIP, int ConnectPort) { this.RemoteAddress = Convert.ToString(ConnectIP); this.RemotePort = ConnectPort; this.ClientEndPoint = new IPEndPoint(ConnectIP, ConnectPort); this.ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); this.ClientSocket.BeginConnect(this.ClientEndPoint, new AsyncCallback(this.ConnectionOpened), null); } public Client(Socket AcceptedSocket, IPEndPoint AcceptedEndPoint) { this.ClientSocket = AcceptedSocket; this.ClientEndPoint = AcceptedEndPoint; this.ClientStream = new NetworkStream(this.ClientSocket) { ReadTimeout = 2000, WriteTimeout = 2000 }; this.RemoteAddress = Convert.ToString(this.ClientEndPoint.Address); this.RemotePort = this.ClientEndPoint.Port; } public abstract void Connected(); public abstract void ConnectFailed(SocketException Exception); private void ConnectionOpened(IAsyncResult AsyncResult) { try { this.ClientSocket.EndConnect(AsyncResult); this.ClientStream = new NetworkStream(this.ClientSocket); this.Connected(); } catch (SocketException socketException) { this.ConnectFailed(socketException); } } public void Disconnect() { if (this.IsConnected == 0 && Interlocked.CompareExchange(ref this.IsConnected, 1, 0) == 0) { this.ClientStream.Write(new byte[0], 0, 0); this.Disconnected(); try { this.ClientStream.Close(0); } catch { } try { this.ClientStream.Dispose(); } catch { } try { this.ClientSocket.Shutdown(SocketShutdown.Both); } catch { } try { this.ClientSocket.Close(0); } catch { } try { this.ClientSocket.Dispose(); } catch { } this.ClientEndPoint = null; this.ClientBuffer = new byte[1]; this.RemoteAddress = string.Empty; this.RemotePort = 0; } } public abstract void Disconnected(); public void Dispose() { this.Disconnect(); } ~Client() { this.Dispose(); } public void Receive() { if (this.IsConnected != 0) { return; } this.ClientBuffer = new byte[1]; try { this.ClientStream.BeginRead(this.ClientBuffer, 0, 1, new AsyncCallback(this.ReceivedSize), null); } catch { this.Disconnect(); } } public abstract void Received(byte[] Buffer); private void ReceivedBigSize(IAsyncResult AsyncResult) { if (this.IsConnected != 0) { return; } try { this.ClientStream.EndRead(AsyncResult); } catch { this.Disconnect(); } short num = BitConverter.ToInt16(this.ClientBuffer, 0); this.ClientBuffer = new byte[num]; try { this.ClientStream.BeginRead(this.ClientBuffer, 0, num, new AsyncCallback(this.ReceivedPacket), null); } catch { this.Disconnect(); } } private void ReceivedPacket(IAsyncResult AsyncResult) { if (this.IsConnected != 0) { return; } try { this.ClientStream.EndRead(AsyncResult); } catch { this.Disconnect(); } this.Received(this.ClientBuffer); this.Receive(); } private void ReceivedSize(IAsyncResult AsyncResult) { if (this.IsConnected != 0) { return; } try { this.ClientStream.EndRead(AsyncResult); } catch { this.Disconnect(); } if (this.ClientBuffer[0] != 0) { this.ClientBuffer = new byte[this.ClientBuffer[0]]; try { this.ClientStream.BeginRead(this.ClientBuffer, 0, (int)this.ClientBuffer.Length, new AsyncCallback(this.ReceivedPacket), null); } catch { this.Disconnect(); } } else { this.ClientBuffer = new byte[2]; try { this.ClientStream.BeginRead(this.ClientBuffer, 0, 2, new AsyncCallback(this.ReceivedBigSize), null); } catch { this.Disconnect(); } } } public void Send(byte[] Buffer) { if (this.IsConnected != 0) { return; } try { this.ClientStream.BeginWrite(Buffer, 0, (int)Buffer.Length, new AsyncCallback(this.Sent), null); } catch { this.Disconnect(); } } private void Sent(IAsyncResult AsyncResult) { if (this.IsConnected != 0) { return; } try { this.ClientStream.EndWrite(AsyncResult); } catch { this.Disconnect(); } } } }