diff --git a/Client/Core/Client.cs b/Client/Core/Client.cs index 03088dbf..beaef4d5 100644 --- a/Client/Core/Client.cs +++ b/Client/Core/Client.cs @@ -11,6 +11,7 @@ using System.IO; using System.Net; using System.Net.Sockets; +using System.Threading; namespace Core { @@ -62,6 +63,8 @@ private void OnClientRead(byte[] e) if (packet.GetType() == typeof(KeepAlive)) new KeepAliveResponse() { TimeSent = ((KeepAlive)packet).TimeSent }.Execute(this); + else if (packet.GetType() == typeof(KeepAliveResponse)) + HandleKeepAlivePacket((KeepAliveResponse)packet, this); else ClientRead(this, packet); } @@ -97,6 +100,8 @@ private void OnClientWrite(IPacket packet, long length, byte[] rawData) private SocketAsyncEventArgs[] _item = new SocketAsyncEventArgs[2]; + private List _keepAlives; + private bool[] _processing = new bool[2]; public int BufferSize { get; set; } @@ -209,6 +214,8 @@ private void Initialize() _sendQueue = new Queue(); + _keepAlives = new List(); + _item[0] = new SocketAsyncEventArgs(); _item[0].Completed += Process; _item[1] = new SocketAsyncEventArgs(); @@ -249,13 +256,20 @@ private void Process(object s, SocketAsyncEventArgs e) switch (e.LastOperation) { case SocketAsyncOperation.Connect: + _endPoint = (IPEndPoint)_handle.RemoteEndPoint; + Connected = true; + _item[0].SetBuffer(new byte[BufferSize], 0, BufferSize); _asyncOperation.Post(x => OnClientState((bool)x), true); + + SendKeepAlives(); + if (!_handle.ReceiveAsync(e)) Process(null, e); + break; case SocketAsyncOperation.Receive: if (!Connected) @@ -317,6 +331,8 @@ public void Disconnect() _handle.Close(); if (_sendQueue != null) _sendQueue.Clear(); + if (_keepAlives != null) + _keepAlives.Clear(); _sendBuffer = new byte[0]; _readBuffer = new byte[0]; @@ -442,5 +458,53 @@ private void HandleRead(byte[] data, int index, int length) Disconnect(); } } + + private void SendKeepAlives() + { + new Thread(() => + { + while (Connected) + { + try + { + KeepAlive keepAlive = new KeepAlive(); + lock (_keepAlives) + { + _keepAlives.Add(keepAlive); + } + keepAlive.Execute(this); + Timer timer = new Timer(KeepAliveCallback, keepAlive, 25000, Timeout.Infinite); + } + catch + { + + } + Thread.Sleep(15000); + } + + }) { IsBackground = true }.Start(); + } + + private void KeepAliveCallback(object state) + { + KeepAlive keepAlive = (KeepAlive)state; + + if (_keepAlives.Contains(keepAlive)) + { + Disconnect(); + } + } + + private void HandleKeepAlivePacket(KeepAliveResponse packet, Client client) + { + foreach (KeepAlive keepAlive in _keepAlives) + { + if (keepAlive.TimeSent == packet.TimeSent && keepAlive.Client == client) + { + _keepAlives.Remove(keepAlive); + break; + } + } + } } } diff --git a/Client/Program.cs b/Client/Program.cs index 35592981..dc58367a 100644 --- a/Client/Program.cs +++ b/Client/Program.cs @@ -11,7 +11,7 @@ static class Program { public static Core.Client _Client; static bool Reconnect = true; - static bool Connected = false; + static volatile bool Connected = false; static Mutex AppMutex; [STAThread] diff --git a/Server/Core/Client.cs b/Server/Core/Client.cs index 7010dc2c..e1abb3b4 100644 --- a/Server/Core/Client.cs +++ b/Server/Core/Client.cs @@ -65,6 +65,8 @@ private void OnClientRead(byte[] e) if (packet.GetType() == typeof(KeepAliveResponse)) _parentServer.HandleKeepAlivePacket((KeepAliveResponse)packet, this); + else if (packet.GetType() == typeof(KeepAlive)) + new KeepAliveResponse() { TimeSent = ((KeepAlive)packet).TimeSent }.Execute(this); else ClientRead(this, packet); } diff --git a/Server/Core/Server.cs b/Server/Core/Server.cs index 01166edd..1fe2943d 100644 --- a/Server/Core/Server.cs +++ b/Server/Core/Server.cs @@ -245,6 +245,8 @@ public void Disconnect() } } + _keepAlives = null; + Listening = false; OnServerState(false); }