using System; using System.Net; using System.Net.Sockets; namespace FilterAPI.Networking { public abstract class DualClientV2 : IDisposable { Config Conf = new Config(); private Socket CSock; public IPEndPoint CIPEP; private Socket SSock; public IPEndPoint SIPEP; private const Int32 CMaxRXBuff = 5120; private Byte[] CRxBuff; private Int32 CRxLen; private const Int32 SMaxRXBuff = 25600; private Byte[] SRxBuff; private Int32 SRxLen; public FiestaCrypto FstCrypto; public DualClientV2(Socket CS, IPEndPoint CEP, IPEndPoint SEP) { CIPEP = CEP; CSock = CS; CSock.LingerState = new LingerOption(true, 2); SIPEP = SEP; SSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // outgoing server socket SSock.LingerState = new LingerOption(true, 2); SSock.BeginConnect(SIPEP, new AsyncCallback(SConnected), null); } private void SConnected(IAsyncResult IAR) { CRxBuff = new byte[CMaxRXBuff]; SRxBuff = new byte[SMaxRXBuff]; RxClient(); RxServer(); } #region ClientRx public void RxClient() { if (disposed) { return; } try { CSock.BeginReceive(CRxBuff, 0, 1, SocketFlags.None, new AsyncCallback(RecdClientSmall), null); } catch { Dispose(); } } private void RecdClientSmall(IAsyncResult IAR) { if (disposed) { return; } Int32 RecdBytes; try { RecdBytes = CSock.EndReceive(IAR); } catch { Dispose(); return; } if (RecdBytes == 1) { CRxLen = CRxBuff[0]; if (CRxLen == 0) { try { CSock.BeginReceive(CRxBuff, 0, 2, SocketFlags.None, new AsyncCallback(RecdClientBig), null); } catch { Dispose(); } } else { try { CSock.BeginReceive(CRxBuff, 0, CRxLen, SocketFlags.None, new AsyncCallback(RecdClientPkt), null); } catch { Dispose(); } } } else { Dispose(); } } private void RecdClientBig(IAsyncResult IAR) { if (disposed) { return; } Int32 RecdBytes; try { RecdBytes = CSock.EndReceive(IAR); } catch { Dispose(); return; } if (RecdBytes == 2) { CRxLen = BitConverter.ToInt16(CRxBuff, 0); try { CSock.BeginReceive(CRxBuff, 0, CRxLen, SocketFlags.None, new AsyncCallback(RecdClientPkt), null); } catch { Dispose(); } } else { Dispose(); } } private void RecdClientPkt(IAsyncResult IAR) { if (disposed) { return; } Int32 RecdBytes; try { RecdBytes = CSock.EndReceive(IAR); } catch { Dispose(); return; } if (RecdBytes == CRxLen) { Byte[] PacketData = new Byte[CRxLen]; Buffer.BlockCopy(CRxBuff, 0, PacketData, 0, CRxLen); RecdClient(PacketData); RxClient(); } else { Dispose(); } } public abstract void RecdClient(Byte[] Buffer); #endregion #region ClientTx public void SendClient(Byte[] Buffer) { if (disposed) { return; } try { CSock.BeginSend(Buffer, 0, Buffer.Length, SocketFlags.None, new AsyncCallback(SentClient), null); } catch { Dispose(); } } private void SentClient(IAsyncResult IAR) { if (disposed) { return; } Int32 SentBytes; try { SentBytes = CSock.EndSend(IAR); } catch { Dispose(); return; } if (SentBytes <= 0) { Dispose(); } } #endregion #region ServerRx private void RxServer() { if (disposed) { return; } try { SSock.BeginReceive(SRxBuff, 0, 1, SocketFlags.None, new AsyncCallback(RecdServerSmall), null); } catch { Dispose(); } } private void RecdServerSmall(IAsyncResult IAR) { if (disposed) { return; } Int32 RecdBytes; try { RecdBytes = SSock.EndReceive(IAR); } catch { Dispose(); return; } if (RecdBytes == 1) { SRxLen = SRxBuff[0]; if (SRxLen == 0) SSock.BeginReceive(SRxBuff, 0, 2, SocketFlags.None, new AsyncCallback(RecdServerBig), null); else SSock.BeginReceive(SRxBuff, 0, SRxLen, SocketFlags.None, new AsyncCallback(RecdServerPkt), null); } else { Dispose(); } } private void RecdServerBig(IAsyncResult IAR) { if (disposed) { return; } Int32 RecdBytes; try { RecdBytes = SSock.EndReceive(IAR); } catch { Dispose(); return; } if (RecdBytes == 2) { SRxLen = BitConverter.ToInt16(SRxBuff, 0); try { SSock.BeginReceive(SRxBuff, 0, SRxLen, SocketFlags.None, new AsyncCallback(RecdServerPkt), null); } catch { Dispose(); } } else { Dispose(); } } private void RecdServerPkt(IAsyncResult IAR) { if (disposed) { return; } Int32 RecdBytes; try { RecdBytes = SSock.EndReceive(IAR); } catch { Dispose(); return; } if (RecdBytes == SRxLen) { Byte[] PacketData = new Byte[SRxLen]; Buffer.BlockCopy(SRxBuff, 0, PacketData, 0, SRxLen); RecdServer(PacketData); RxServer(); } else { Dispose(); } } public abstract void RecdServer(Byte[] Buffer); #endregion #region ServerTx public void SendServer(Byte[] Buffer) { if (disposed) { return; } try { SSock.BeginSend(Buffer, 0, Buffer.Length, SocketFlags.None, new AsyncCallback(SentServer), null); } catch { Dispose(); } } private void SentServer(IAsyncResult IAR) { if (disposed) { return; } Int32 SentBytes; try { SentBytes = SSock.EndSend(IAR); } catch { Dispose(); return; } if (SentBytes <= 0) { Dispose(); } } #endregion public abstract void Disconnected(); #region IDisposable Support private bool disposed = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { if (SSock != null) { try { SSock.Close(); SSock.Dispose(); } catch { } } if (CSock != null) { try { CSock.Close(); CSock.Dispose(); } catch { } } } disposed = true; Disconnected(); } } public void Dispose() { Dispose(true); } ~DualClientV2() { Dispose(false); } #endregion } }